update to swagger 2.0

This commit is contained in:
Tony Tam 2014-08-29 09:47:17 -07:00
parent dbf04a9563
commit c5ccc0a908
98 changed files with 1 additions and 14801 deletions

View File

@ -1,3 +0,0 @@
language: scala
scala:
- 2.10.0

11
LICENSE
View File

@ -1,11 +0,0 @@
Copyright 2014 Reverb Technologies, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at [apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

246
README.md
View File

@ -1,246 +0,0 @@
# Swagger Code Generator
[![Build Status](https://travis-ci.org/wordnik/swagger-codegen.png)](https://travis-ci.org/wordnik/swagger-codegen)
## Overview
This is the swagger codegen project, which allows generation of client libraries automatically from a
Swagger-compliant server.
## What's Swagger?
The goal of Swagger™ is to define a standard, language-agnostic interface to REST APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined via Swagger, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interfaces have done for lower-level programming, Swager removes the guesswork in calling the service.
Check out [Swagger-Spec](https://github.com/wordnik/swagger-spec) for additional information about the Swagger project, including additional libraries with support for other languages and more.
### Prerequisites
You need the following installed and available in your $PATH:
* [Java 1.7](http://java.oracle.com)
Note! Some folks have had issues with OOM errors with java version "1.6.0_51". It's strongly suggested that you upgrade to 1.7!
* [Apache maven 3.0.3 or greater](http://maven.apache.org/)
* [Scala 2.9.1](http://www.scala-lang.org)
* [sbt (only download if you're building on Windows)](http://www.scala-sbt.org/)
You also need to add the scala binary to your PATH.
After cloning the project, you need to build it from source with this command:
```
./sbt assembly
```
or for Windows...
```
sbt assembly
```
### To generate a sample client library
You can build a client against Wordnik's [petstore](http://petstore.swagger.wordnik.com) API as follows:
```
./bin/scala-petstore.sh
```
This will run the script in [samples/client/petstore/ScalaPetstoreCodegen.scala](https://github.com/wordnik/swagger-codegen/blob/master/samples/client/petstore/scala/ScalaPetstoreCodegen.scala) and create the client. You can then
compile and run the client, as well as unit tests against it:
```
cd samples/client/petstore/scala
mvn package
```
Other languages have petstore samples, too:
```
./bin/flash-petstore.sh
./bin/java-petstore.sh
./bin/objc-petstore.sh
./bin/php-petstore.sh
./bin/python-petstore.sh
./bin/python3-petstore.sh
./bin/ruby-petstore.sh
```
### Generating libraries from your server
It's just as easy--you can either run the default generators:
```
./bin/runscala.sh com.wordnik.swagger.codegen.BasicScalaGenerator http://petstore.swagger.wordnik.com/api/api-docs special-key
```
Replace `Scala` with `Flash`, `Java`, `Objc`, `PHP`, `Python`, `Python3`, `Ruby`.
You will probably want to override some of the defaults--like packages, etc. For doing this, just create a scala
script with the overrides you want. Follow [ScalaPetstoreCodegen](https://github.com/wordnik/swagger-codegen/blob/master/samples/client/petstore/scala/ScalaPetstoreCodegen.scala) as an example:
For example, create `src/main/scala/MyCodegen.scala` with these contents:
```scala
import com.wordnik.swagger.codegen.BasicScalaGenerator
object MyCodegen extends BasicScalaGenerator {
def main(args: Array[String]) = generateClient(args)
// location of templates
override def templateDir = "scala"
// where to write generated code
override def destinationDir = "client/scala/src/main/scala"
// api invoker package
override def invokerPackage = "com.myapi.client"
// package for models
override def modelPackage = Some("com.myapi.client.model")
// package for api classes
override def apiPackage = Some("com.myapi.client.api")
// supporting classes
override def supportingFiles = List(
("apiInvoker.mustache", destinationDir + java.io.File.separator + packageName.replaceAll("\\.", java.io.File.separator), "ApiInvoker.scala"),
("pom.mustache", destinationDir, "pom.xml")
)
}
```
Now you can generate your client like this:
```
./bin/runscala.sh src/main/scala/MyCodegen.scala http://my.api.com/resources.json super-secret-key
```
w00t! Thanks to the scala interpretor, you didn't even need to recompile.
### Modifying the client library format
Don't like the default swagger client syntax? Want a different language supported? No problem! Swagger codegen
processes mustache templates with the [scalate](http://scalate.fusesource.org/) engine. You can modify our templates or
make your own.
You can look at `src/main/resources/${your-language}` for examples. To make your own templates, create your own files
and override the `templateDir` in your script to point to the right place. It actually is that easy.
### Where is Javascript???
See our [javascript library](http://github.com/wordnik/swagger.js)--it's completely dynamic and doesn't require
static code generation.
There is a third-party component called [swagger-js-codegen](https://github.com/wcandillon/swagger-js-codegen) that can generate angularjs or nodejs source code from a swagger specification.
#### Generating a client from flat files (i.e. no remote server calls)
If you don't want to call your server, you can save the swagger spec files into a directory and pass an argument
to the code generator like this:
```
-DfileMap=/path/to/resource-listing
```
Or for example:
```
./bin/java-petstore-filemap.sh
```
Which simple passes `-DfileMap=src/test/resources/petstore` as an argument. Great for creating libraries on your
ci server... or while coding on an airplane.
### Validating your swagger spec
You can use the validation tool to see that your server is creating a proper spec file. If you want to learn
more about the spec file and format, please see [swagger-core](https://github.com/wordnik/swagger-core/wiki). This
tool will read the server and generate a report of any violations of the spec. If there are violations, the
client codegen and ui may not work correctly.
To validate an api and write output to ./swagger-errors.html:
```
./bin/validate.sh http://petstore.swagger.wordnik.com/api/api-docs "specia-key" ./swagger-errors.html
```
### Generating static api documentation
If you need to make static pages or don't want the sandbox of the swagger-ui, you can use the codegen to build them. Remember, the engine is just using mustache templates--the output format is your call.
```
./bin/static-docs.sh
```
Will produce the output here:
```
https://github.com/wordnik/swagger-codegen/tree/master/samples/docs/swagger-static-docs
```
which is based on these templates:
```
https://github.com/wordnik/swagger-codegen/tree/master/src/main/resources/swagger-static
```
and looks like this
![Image](https://raw.github.com/wordnik/swagger-codegen/master/samples/docs/swagger-static-docs/static-docs.png)
### To build a server stub
You can also use the codegen to generate a server for a couple different frameworks. Take a look here:
* [javascript node.js Server generator](https://github.com/wordnik/swagger-codegen/tree/master/samples/server-generator/node)
* [ruby sinatra generator](https://github.com/wordnik/swagger-codegen/tree/master/samples/server-generator/sinatra)
* [scala scalatra generator](https://github.com/wordnik/swagger-codegen/tree/master/samples/server-generator/scalatra)
* [java jax-rs generator](https://github.com/wordnik/swagger-codegen/tree/master/samples/server-generator/java-jaxrs)
### Migrating from Swagger 1.1 to 1.2 format
If you've spent time hand-crafting your swagger spec files, you can use the [SpecConverter](https://github.com/wordnik/swagger-codegen/blob/master/src/main/scala/com/wordnik/swagger/codegen/SpecConverter.scala) to do the dirty work. For example:
```bash
$ ./bin/update-spec.sh http://developer.wordnik.com/v4/resources.json wordnik-developer
writing file wordnik-developer/api-docs
calling: http://developer.wordnik.com/v4/account.json
calling: http://developer.wordnik.com/v4/word.json
calling: http://developer.wordnik.com/v4/words.json
calling: http://developer.wordnik.com/v4/wordList.json
calling: http://developer.wordnik.com/v4/wordLists.json
writing file wordnik-developer/account
writing file wordnik-developer/word
writing file wordnik-developer/words
writing file wordnik-developer/wordList
writing file wordnik-developer/wordLists
```
Will read the 1.1 spec from wordnik developer and write it into the folder called `wordnik-developer`.
### To build the codegen library
This will create the swagger-codegen library from source.
```
./sbt assembly
```
Note! The templates are included in the library generated. If you want to modify the templates, you'll need to
either repackage the library OR modify your codegen script to use a file path!
License
-------
Copyright 2014 Wordnik, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at [apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,8 +0,0 @@
val version = scala.util.Properties.scalaPropOrElse("version.number", "unknown").toString match {
case "2.10.0" => "2.10"
case "2.10.2" => "2.10"
case "2.10.3" => "2.10"
case "2.10.4" => "2.10"
case e: String => e
}
println(version)

View File

@ -1,37 +0,0 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
./bin/java-wordnik-api.sh
./bin/php-wordnik-api.sh
./bin/python3-wordnik-api.sh
./bin/objc-wordnik-api.sh
./bin/python-wordnik-api.sh
./bin/scala-wordnik-api.sh
./bin/android-java-petstore.sh
./bin/csharp-petstore.sh
./bin/flash-petstore.sh
./bin/java-petstore.sh
./bin/objc-petstore.sh
./bin/php-petstore.sh
./bin/python-petstore.sh
./bin/python3-petstore.sh
./bin/ruby-petstore.sh
./bin/scala-petstore.sh

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/android-java/AndroidJavaPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/android-java/AndroidJavaPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/csharp/CsharpPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties "
ags="$@ samples/client/petstore/flash/FlashPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DfileMap=src/test/resources/petstore-1.2/api-docs -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/java/JavaPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/java/JavaPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
ags="$@ samples/client/wordnik-api/java/JavaWordnikApiCodegen.scala http://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,34 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
version="$(scala ./bin/Version.scala)"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/objc/ObjcPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
ags="$@ samples/client/wordnik-api/objc/ObjcWordnikApiCodegen.scala http://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/php/PHPPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
ags="$@ samples/client/wordnik-api/php/PHPWordnikApiCodegen.scala http://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/python/PythonPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
ags="$@ samples/client/wordnik-api/python/PythonWordnikApiCodegen.scala http://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/python3/Python3PetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
ags="$@ samples/client/wordnik-api/python3/Python3WordnikApiCodegen.scala http://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/ruby/RubyPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,31 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=2.10 #$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
ags="com.wordnik.swagger.codegen.ScalaAsyncClientGenerator $@"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
java -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
ags="$@ samples/client/petstore/scala/ScalaPetstoreCodegen.scala http://petstore.swagger.wordnik.com/api/api-docs special-key"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
ags="$@ samples/client/wordnik-api/scala/ScalaWordnikApiCodegen.scala http://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,32 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties "
ags="$@ com.wordnik.swagger.codegen.SwaggerDocGenerator http://petstore.swagger.wordnik.com/api/api-docs"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,31 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
ags="com.wordnik.swagger.codegen.SpecConverter $@"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,31 +0,0 @@
#!/bin/sh
SCRIPT="$0"
SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
SCRIPT="$link"
else
SCRIPT=`dirname "$SCRIPT"`/"$link"
fi
done
if [ ! -d "${APP_DIR}" ]; then
APP_DIR=`dirname "$SCRIPT"`/..
APP_DIR=`cd "${APP_DIR}"; pwd`
fi
cd $APP_DIR
# if you've executed sbt assembly previously it will use that instead.
ags="com.wordnik.swagger.codegen.spec.Validator $@"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/*assembly*.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi

View File

@ -1,56 +0,0 @@
fs = require('fs')
yaml = require('js-yaml')
var args = process.argv.splice(2);
if(args.length == 0) {
process.exit(1);
}
var arg0 = args[0];
var outputdir = ".";
if(args.length > 1) {
outputdir = args[1];
}
var file = fs.lstatSync(arg0);
if(file.isFile()) {
convert(arg0, outputdir);
}
else if (file.isDirectory()) {
var files = fs.readdirSync(arg0);
files.map(function(item) {
var filename = arg0 + "/" + item;
var file = fs.lstatSync(filename);
if(file.isFile()) {
convert(filename, outputdir);
}
});
}
function convert(filename, outputdir) {
console.log("converting " + filename);
fs.readFile(filename, "utf8", function (err, data) {
if(err) {
console.log(err);
}
else {
try {
var js = yaml.load(data);
var prettyJs = JSON.stringify(js, undefined, 2);
var outputFilename = outputdir + "/" + filename.split("/").pop().replace(".yml", "") + ".json";
console.log("writing to " + outputFilename);
fs.writeFile(outputFilename, prettyJs, function(err) {
if(err) {
console.log(err);
}
});
}
catch (err) {
console.log(err);
}
}
});
}

136
build.sbt
View File

@ -1,136 +0,0 @@
import xml.Group
import AssemblyKeys._
organization := "com.wordnik"
name := "swagger-codegen"
version := "2.0.18-SNAPSHOT"
crossVersion := CrossVersion.full
javacOptions ++= Seq("-target", "1.6", "-source", "1.6", "-Xlint:unchecked", "-Xlint:deprecation")
scalacOptions ++= Seq("-optimize", "-unchecked", "-deprecation", "-Xcheckinit", "-encoding", "utf8")
crossScalaVersions := Seq("2.10.0", "2.10.1", "2.10.2", "2.10.3", "2.10.4", "2.11.0", "2.11.1")
scalaVersion := "2.10.4"
libraryDependencies ++= Seq(
"org.json4s" %% "json4s-jackson" % "3.2.10",
"io.backchat.inflector" %% "scala-inflector" % "1.3.5",
"commons-io" % "commons-io" % "2.3",
"ch.qos.logback" % "logback-classic" % "1.0.13" % "provided",
"org.rogach" %% "scallop" % "0.9.5",
"junit" % "junit" % "4.11" % "test",
"org.scalatest" %% "scalatest" % "2.1.7" % "test"
)
libraryDependencies <+= scalaVersion {
case v if v.startsWith("2.9") =>
"org.fusesource.scalate" % "scalate-core_2.9" % "1.6.1"
case v if v.startsWith("2.10") =>
"org.scalatra.scalate" %% "scalate-core" % "1.7.0"
case v if v.startsWith("2.11") =>
"org.scalatra.scalate" %% "scalate-core" % "1.7.0"
}
libraryDependencies ++= {
scalaVersion.toString match {
case v if v.startsWith("2.10") || v.startsWith("2.11") => Seq("org.scala-lang" % "scala-reflect" % v)
case _ => Seq()
}
}
resolvers += "Typesafe releases" at "http://repo.typesafe.com/typesafe/releases"
packageOptions <+= (name, version, organization) map {
(title, version, vendor) =>
Package.ManifestAttributes(
"Created-By" -> "Simple Build Tool",
"Built-By" -> System.getProperty("user.name"),
"Build-Jdk" -> System.getProperty("java.version"),
"Specification-Title" -> title,
"Specification-Version" -> version,
"Specification-Vendor" -> vendor,
"Implementation-Title" -> title,
"Implementation-Version" -> version,
"Implementation-Vendor-Id" -> vendor,
"Implementation-Vendor" -> vendor
)
}
publishTo <<= (version) { version: String =>
if (version.trim.endsWith("SNAPSHOT"))
Some("Sonatype Nexus Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots")
else
Some("Sonatype Nexus Releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2")
}
// publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))
artifact in (Compile, assembly) ~= { art =>
art.copy(`classifier` = Some("assembly"))
}
addArtifact(artifact in (Compile, assembly), assembly)
publishMavenStyle := true
publishArtifact in Test := false
pomIncludeRepository := { x => false }
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
homepage := Some(new URL("https://github.com/wordnik/swagger-codegen"))
parallelExecution in Test := false
startYear := Some(2009)
licenses := Seq(("Apache License 2.0", new URL("http://www.apache.org/licenses/LICENSE-2.0.html")))
pomExtra <<= (pomExtra, name, description) {(pom, name, desc) => pom ++ Group(
<scm>
<connection>scm:git:git@github.com:wordnik/swagger-codegen.git</connection>
<developerConnection>scm:git:git@github.com:wordnik/swagger-codegen.git</developerConnection>
<url>https://github.com/wordnik/swagger-codegen</url>
</scm>
<issueManagement>
<system>github</system>
<url>https://github.com/wordnik/swagger-codegen/issues</url>
</issueManagement>
<developers>
<developer>
<id>rpidikiti</id>
<name>Ramesh Pidikiti</name>
<email>ramesh@wordnik.com</email>
</developer>
<developer>
<id>ayush</id>
<name>Ayush Gupta</name>
<email>ayush@glugbot.com</email>
</developer>
<developer>
<id>fehguy</id>
<name>Tony Tam</name>
<email>fehguy@gmail.com</email>
</developer>
<developer>
<id>casualjim</id>
<name>Ivan Porto Carrero</name>
<url>http://flanders.co.nz/</url>
</developer>
<developer>
<id>radius314</id>
<name>Danny Gershman</name>
<email>danny.gershman@gmail.com</email>
</developer>
</developers>
)}
assemblySettings
// jarName in assembly := "swagger-codegen.jar"

View File

@ -1,124 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>5</version>
</parent>
<groupId>com.wordnik</groupId>
<artifactId>swagger-codegen-distribution</artifactId>
<packaging>jar</packaging>
<version>2.0.2-SNAPSHOT</version>
<name>swagger-codegen-distribution</name>
<url>https://github.com/wordnik/swagger-codegen</url>
<scm>
<connection>scm:git:git@github.com:wordnik/swagger-codegen.git</connection>
<developerConnection>scm:git:git@github.com:wordnik/swagger-codegen.git</developerConnection>
<url>https://github.com/wordnik/swagger-codegen</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<developers>
<developer>
<id>fehguy</id>
<name>Tony Tam</name>
<email>fehguy@gmail.com</email>
</developer>
</developers>
<issueManagement>
<system>github</system>
<url>https://github.com/wordnik/swagger-codegen/issues</url>
</issueManagement>
<mailingLists>
<mailingList>
<name>wordnik-api</name>
<archive>https://groups.google.com/forum/#!forum/wordnik-api</archive>
</mailingList>
</mailingLists>
<licenses>
<license>
<name>Apache License 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<executions>
<execution>
<id>distro-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>src-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>com.wordnik</includeGroupIds>
<includeArtifactIds>text-data</includeArtifactIds>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-codegen_2.9.1</artifactId>
<version>${swagger.codegen.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<swagger.codegen.version>2.0.2-SNAPSHOT</swagger.codegen.version>
</properties>
</project>

View File

@ -1,29 +0,0 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>distribution</id>
<baseDirectory>swagger-codegen</baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<dependencySets>
<dependencySet>
<scope>compile</scope>
<outputDirectory>target/lib</outputDirectory>
<includes>
<include>*:jar:*</include>
</includes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>../bin</directory>
<includes>
<include>*.*</include>
</includes>
<outputDirectory>bin</outputDirectory>
</fileSet>
</fileSets>
</assembly>

View File

@ -1,16 +0,0 @@
{
"name": "swagger-yaml",
"version": "2.0.1",
"description": "Converts yaml to swagger json",
"author": {
"name": "Tony Tam",
"email": "fehguy@gmail.com",
"url": "http://developer.wordnik.com"
},
"license": "Apache",
"readmeFilename": "README.md",
"dependencies": {
"json2yaml": "~1.0",
"js-yaml": "~3.0"
}
}

View File

@ -1 +0,0 @@
sbt.version=0.13.0

View File

@ -1,5 +0,0 @@
addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.2")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.9.1")
resolvers += "Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases"

518
sbt
View File

@ -1,518 +0,0 @@
#!/usr/bin/env bash
#
# A more capable sbt runner, coincidentally also called sbt.
# Author: Paul Phillips <paulp@typesafe.com>
# todo - make this dynamic
declare -r sbt_release_version=0.12.4
declare -r sbt_beta_version=0.13.0-RC4
declare -r sbt_snapshot_version=0.13.0-SNAPSHOT
declare sbt_jar sbt_dir sbt_create sbt_snapshot sbt_launch_dir
declare scala_version java_home sbt_explicit_version
declare verbose debug quiet noshare batch trace_level log_level
declare sbt_saved_stty
echoerr () { [[ -z $quiet ]] && echo "$@" >&2; }
vlog () { [[ -n "$verbose$debug" ]] && echoerr "$@"; }
dlog () { [[ -n $debug ]] && echoerr "$@"; }
# we'd like these set before we get around to properly processing arguments
for arg in "$@"; do
case $arg in
-q|-quiet) quiet=true ;;
-d|-debug) debug=true ;;
-v|-verbose) verbose=true ;;
*) ;;
esac
done
build_props_sbt () {
if [[ -r project/build.properties ]]; then
versionLine=$(grep ^sbt.version project/build.properties | tr -d '\r')
versionString=${versionLine##sbt.version=}
echo "$versionString"
fi
}
update_build_props_sbt () {
local ver="$1"
local old=$(build_props_sbt)
if [[ $ver == $old ]]; then
return
elif [[ -r project/build.properties ]]; then
perl -pi -e "s/^sbt\.version=.*\$/sbt.version=${ver}/" project/build.properties
grep -q '^sbt.version=' project/build.properties || echo "sbt.version=${ver}" >> project/build.properties
echoerr !!!
echoerr !!! Updated file project/build.properties setting sbt.version to: $ver
echoerr !!! Previous value was: $old
echoerr !!!
fi
}
sbt_version () {
if [[ -n $sbt_explicit_version ]]; then
echo $sbt_explicit_version
else
local v=$(build_props_sbt)
if [[ -n $v ]]; then
echo $v
else
echo $sbt_release_version
fi
fi
}
# restore stty settings (echo in particular)
onSbtRunnerExit() {
[[ -n $sbt_saved_stty ]] || return
dlog ""
dlog "restoring stty: $sbt_saved_stty"
stty $sbt_saved_stty
unset sbt_saved_stty
}
# save stty and trap exit, to ensure echo is reenabled if we are interrupted.
trap onSbtRunnerExit EXIT
sbt_saved_stty=$(stty -g 2>/dev/null)
dlog "Saved stty: $sbt_saved_stty"
# this seems to cover the bases on OSX, and someone will
# have to tell me about the others.
get_script_path () {
local path="$1"
[[ -L "$path" ]] || { echo "$path" ; return; }
local target=$(readlink "$path")
if [[ "${target:0:1}" == "/" ]]; then
echo "$target"
else
echo "$(dirname $path)/$target"
fi
}
die() {
echo "Aborting: $@"
exit 1
}
make_url () {
groupid="$1"
category="$2"
version="$3"
echo "http://typesafe.artifactoryonline.com/typesafe/ivy-$category/$groupid/sbt-launch/$version/sbt-launch.jar"
}
readarr () {
while read ; do
eval "$1+=(\"$REPLY\")"
done
}
init_default_option_file () {
local overriding_var=${!1}
local default_file=$2
if [[ ! -r "$default_file" && $overriding_var =~ ^@(.*)$ ]]; then
local envvar_file=${BASH_REMATCH[1]}
if [[ -r $envvar_file ]]; then
default_file=$envvar_file
fi
fi
echo $default_file
}
declare -r default_jvm_opts="-Dfile.encoding=UTF8 -XX:MaxPermSize=256m -Xms512m -Xmx1g -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC"
declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy"
declare -r latest_28="2.8.2"
declare -r latest_29="2.9.3"
declare -r latest_210="2.10.0"
declare -r script_path=$(get_script_path "$BASH_SOURCE")
declare -r script_dir="$(dirname $script_path)"
declare -r script_name="$(basename $script_path)"
# some non-read-onlies set with defaults
declare java_cmd=java
declare sbt_opts_file=$(init_default_option_file SBT_OPTS .sbtopts)
declare jvm_opts_file=$(init_default_option_file JVM_OPTS .jvmopts)
# pull -J and -D options to give to java.
declare -a residual_args
declare -a java_args
declare -a scalac_args
declare -a sbt_commands
# args to jvm/sbt via files or environment variables
declare -a extra_jvm_opts extra_sbt_opts
# if set, use JAVA_HOME over java found in path
[[ -e "$JAVA_HOME/bin/java" ]] && java_cmd="$JAVA_HOME/bin/java"
# directory to store sbt launchers
declare sbt_launch_dir="$HOME/.sbt/launchers"
[[ -d "$sbt_launch_dir" ]] || mkdir -p "$sbt_launch_dir"
[[ -w "$sbt_launch_dir" ]] || sbt_launch_dir="$(mktemp -d -t sbt_extras_launchers)"
build_props_scala () {
if [[ -r project/build.properties ]]; then
versionLine=$(grep ^build.scala.versions project/build.properties)
versionString=${versionLine##build.scala.versions=}
echo ${versionString%% .*}
fi
}
execRunner () {
# print the arguments one to a line, quoting any containing spaces
[[ $verbose || $debug ]] && echo "# Executing command line:" && {
for arg; do
if [[ -n "$arg" ]]; then
if printf "%s\n" "$arg" | grep -q ' '; then
printf "\"%s\"\n" "$arg"
else
printf "%s\n" "$arg"
fi
fi
done
echo ""
}
if [[ -n $batch ]]; then
# the only effective way I've found to avoid sbt hanging when backgrounded.
exec 0<&-
( "$@" & )
# I'm sure there's some way to get our hands on the pid and wait for it
# but it exceeds my present level of ambition.
else
{ "$@"; }
fi
}
sbt_groupid () {
case $(sbt_version) in
0.7.*) echo org.scala-tools.sbt ;;
0.10.*) echo org.scala-tools.sbt ;;
0.11.[12]) echo org.scala-tools.sbt ;;
*) echo org.scala-sbt ;;
esac
}
sbt_artifactory_list () {
local version0=$(sbt_version)
local version=${version0%-SNAPSHOT}
local url="http://typesafe.artifactoryonline.com/typesafe/ivy-snapshots/$(sbt_groupid)/sbt-launch/"
dlog "Looking for snapshot list at: $url "
curl -s --list-only "$url" | \
grep -F $version | \
perl -e 'print reverse <>' | \
perl -pe 's#^<a href="([^"/]+).*#$1#;'
}
make_release_url () {
make_url $(sbt_groupid) releases $(sbt_version)
}
# argument is e.g. 0.13.0-SNAPSHOT
# finds the actual version (with the build id) at artifactory
make_snapshot_url () {
for ver in $(sbt_artifactory_list); do
local url=$(make_url $(sbt_groupid) snapshots $ver)
dlog "Testing $url"
curl -s --head "$url" >/dev/null
dlog "curl returned: $?"
echo "$url"
return
done
}
jar_url () {
case $(sbt_version) in
0.7.*) echo "http://simple-build-tool.googlecode.com/files/sbt-launch-0.7.7.jar" ;;
*-SNAPSHOT) make_snapshot_url ;;
*) make_release_url ;;
esac
}
jar_file () {
case $1 in
0.13.*) echo "$sbt_launch_dir/$1/sbt-launch.jar" ;;
*) echo "$sbt_launch_dir/$sbt_release_version/sbt-launch.jar" ;;
esac
}
download_url () {
local url="$1"
local jar="$2"
echo "Downloading sbt launcher $(sbt_version):"
echo " From $url"
echo " To $jar"
mkdir -p $(dirname "$jar") && {
if which curl >/dev/null; then
curl --fail --silent "$url" --output "$jar"
elif which wget >/dev/null; then
wget --quiet -O "$jar" "$url"
fi
} && [[ -r "$jar" ]]
}
acquire_sbt_jar () {
sbt_url="$(jar_url)"
sbt_jar="$(jar_file $(sbt_version))"
[[ -r "$sbt_jar" ]] || download_url "$sbt_url" "$sbt_jar"
}
usage () {
cat <<EOM
Usage: $script_name [options]
-h | -help print this message
-v | -verbose this runner is chattier
-d | -debug set sbt log level to Debug
-q | -quiet set sbt log level to Error
-trace <level> display stack traces with a max of <level> frames (default: -1, traces suppressed)
-no-colors disable ANSI color codes
-sbt-create start sbt even if current directory contains no sbt project
-sbt-dir <path> path to global settings/plugins directory (default: ~/.sbt/<version>)
-sbt-boot <path> path to shared boot directory (default: ~/.sbt/boot in 0.11+)
-ivy <path> path to local Ivy repository (default: ~/.ivy2)
-no-share use all local caches; no sharing
-offline put sbt in offline mode
-jvm-debug <port> Turn on JVM debugging, open at the given port.
-batch Disable interactive mode
-prompt <expr> Set the sbt prompt; in expr, 's' is the State and 'e' is Extracted
# sbt version (default: from project/build.properties if present, else latest release)
!!! The only way to accomplish this pre-0.12.0 if there is a build.properties file which
!!! contains an sbt.version property is to update the file on disk. That's what this does.
-sbt-version <version> use the specified version of sbt (default: $sbt_release_version)
-sbt-jar <path> use the specified jar as the sbt launcher
-sbt-beta use a beta version of sbt (currently: $sbt_beta_version)
-sbt-snapshot use a snapshot version of sbt (currently: $sbt_snapshot_version)
-sbt-launch-dir <path> directory to hold sbt launchers (default: $sbt_launch_dir)
# scala version (default: as chosen by sbt)
-28 use $latest_28
-29 use $latest_29
-210 use $latest_210
-scala-home <path> use the scala build at the specified directory
-scala-version <version> use the specified version of scala
-binary-version <version> use the specified scala version when searching for dependencies
# java version (default: java from PATH, currently $(java -version 2>&1 | grep version))
-java-home <path> alternate JAVA_HOME
# passing options to the jvm - note it does NOT use JAVA_OPTS due to pollution
# The default set is used if JVM_OPTS is unset and no -jvm-opts file is found
<default> $default_jvm_opts
JVM_OPTS environment variable holding either the jvm args directly, or
the reference to a file containing jvm args if given path is prepended by '@' (e.g. '@/etc/jvmopts')
Note: "@"-file is overridden by local '.jvmopts' or '-jvm-opts' argument.
-jvm-opts <path> file containing jvm args (if not given, .jvmopts in project root is used if present)
-Dkey=val pass -Dkey=val directly to the jvm
-J-X pass option -X directly to the jvm (-J is stripped)
# passing options to sbt, OR to this runner
SBT_OPTS environment variable holding either the sbt args directly, or
the reference to a file containing sbt args if given path is prepended by '@' (e.g. '@/etc/sbtopts')
Note: "@"-file is overridden by local '.sbtopts' or '-sbt-opts' argument.
-sbt-opts <path> file containing sbt args (if not given, .sbtopts in project root is used if present)
-S-X add -X to sbt's scalacOptions (-S is stripped)
EOM
}
addJava () {
dlog "[addJava] arg = '$1'"
java_args=( "${java_args[@]}" "$1" )
}
addSbt () {
dlog "[addSbt] arg = '$1'"
sbt_commands=( "${sbt_commands[@]}" "$1" )
}
addScalac () {
dlog "[addScalac] arg = '$1'"
scalac_args=( "${scalac_args[@]}" "$1" )
}
addResidual () {
dlog "[residual] arg = '$1'"
residual_args=( "${residual_args[@]}" "$1" )
}
addResolver () {
addSbt "set resolvers in ThisBuild += $1"
}
addDebugger () {
addJava "-Xdebug"
addJava "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1"
}
setScalaVersion () {
addSbt "set scalaVersion in ThisBuild := \"$1\""
if [[ "$1" == *SNAPSHOT* ]]; then
addResolver Opts.resolver.sonatypeSnapshots
fi
}
process_args ()
{
require_arg () {
local type="$1"
local opt="$2"
local arg="$3"
if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then
die "$opt requires <$type> argument"
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
-h|-help) usage; exit 1 ;;
-v|-verbose) verbose=true && log_level=Info && shift ;;
-d|-debug) debug=true && log_level=Debug && shift ;;
-q|-quiet) quiet=true && log_level=Error && shift ;;
-trace) require_arg integer "$1" "$2" && trace_level=$2 && shift 2 ;;
-ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;;
-no-colors) addJava "-Dsbt.log.noformat=true" && shift ;;
-no-share) noshare=true && shift ;;
-sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;;
-sbt-dir) require_arg path "$1" "$2" && sbt_dir="$2" && shift 2 ;;
-debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;;
-offline) addSbt "set offline := true" && shift ;;
-jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;;
-batch) batch=true && shift ;;
-prompt) require_arg "expr" "$1" "$2" && addSbt "set shellPrompt in ThisBuild := (s => { val e = Project.extract(s) ; $2 })" && shift 2 ;;
-sbt-create) sbt_create=true && shift ;;
-sbt-snapshot) sbt_explicit_version=$sbt_snapshot_version && shift ;;
-sbt-beta) sbt_explicit_version=$sbt_beta_version && shift ;;
-sbt-jar) require_arg path "$1" "$2" && sbt_jar="$2" && shift 2 ;;
-sbt-version) require_arg version "$1" "$2" && sbt_explicit_version="$2" && shift 2 ;;
-sbt-launch-dir) require_arg path "$1" "$2" && sbt_launch_dir="$2" && shift 2 ;;
-scala-version) require_arg version "$1" "$2" && setScalaVersion "$2" && shift 2 ;;
-binary-version) require_arg version "$1" "$2" && addSbt "set scalaBinaryVersion in ThisBuild := \"$2\"" && shift 2 ;;
-scala-home) require_arg path "$1" "$2" && addSbt "set every scalaHome := Some(file(\"$2\"))" && shift 2 ;;
-java-home) require_arg path "$1" "$2" && java_cmd="$2/bin/java" && shift 2 ;;
-sbt-opts) require_arg path "$1" "$2" && sbt_opts_file="$2" && shift 2 ;;
-jvm-opts) require_arg path "$1" "$2" && jvm_opts_file="$2" && shift 2 ;;
-D*) addJava "$1" && shift ;;
-J*) addJava "${1:2}" && shift ;;
-S*) addScalac "${1:2}" && shift ;;
-28) addSbt "++ $latest_28" && shift ;;
-29) addSbt "++ $latest_29" && shift ;;
-210) addSbt "++ $latest_210" && shift ;;
*) addResidual "$1" && shift ;;
esac
done
}
# process the direct command line arguments
process_args "$@"
# skip #-styled comments
readConfigFile() {
while read line; do echo ${line/\#*/} | grep -vE '^\s*$'; done < $1
}
# if there are file/environment sbt_opts, process again so we
# can supply args to this runner
if [[ -r "$sbt_opts_file" ]]; then
vlog "Using sbt options defined in file $sbt_opts_file"
readarr extra_sbt_opts < <(readConfigFile "$sbt_opts_file")
elif [[ -n "$SBT_OPTS" && !($SBT_OPTS =~ ^@.*) ]]; then
vlog "Using sbt options defined in variable \$SBT_OPTS"
extra_sbt_opts=( $SBT_OPTS )
else
vlog "No extra sbt options have been defined"
fi
[[ -n $extra_sbt_opts ]] && process_args "${extra_sbt_opts[@]}"
# reset "$@" to the residual args
set -- "${residual_args[@]}"
argumentCount=$#
# only exists in 0.12+
setTraceLevel() {
case $(sbt_version) in
0.{7,10,11}.*) echoerr "Cannot set trace level in sbt version $(sbt_version)" ;;
*) addSbt "set every traceLevel := $trace_level" ;;
esac
}
# set scalacOptions if we were given any -S opts
[[ ${#scalac_args[@]} -eq 0 ]] || addSbt "set scalacOptions in ThisBuild += \"${scalac_args[@]}\""
# Update build.properties no disk to set explicit version - sbt gives us no choice
[[ -n "$sbt_explicit_version" ]] && update_build_props_sbt "$sbt_explicit_version"
vlog "Detected sbt version $(sbt_version)"
[[ -n "$scala_version" ]] && echoerr "Overriding scala version to $scala_version"
# no args - alert them there's stuff in here
(( $argumentCount > 0 )) || vlog "Starting $script_name: invoke with -help for other options"
# verify this is an sbt dir or -create was given
[[ -r ./build.sbt || -d ./project || -n "$sbt_create" ]] || {
cat <<EOM
$(pwd) doesn't appear to be an sbt project.
If you want to start sbt anyway, run:
$0 -sbt-create
EOM
exit 1
}
# pick up completion if present; todo
[[ -r .sbt_completion.sh ]] && source .sbt_completion.sh
# no jar? download it.
[[ -r "$sbt_jar" ]] || acquire_sbt_jar || {
# still no jar? uh-oh.
echo "Download failed. Obtain the jar manually and place it at $sbt_jar"
exit 1
}
if [[ -n $noshare ]]; then
addJava "$noshare_opts"
else
[[ -n "$sbt_dir" ]] || {
sbt_dir=~/.sbt/$(sbt_version)
vlog "Using $sbt_dir as sbt dir, -sbt-dir to override."
}
addJava "-Dsbt.global.base=$sbt_dir"
fi
if [[ -r "$jvm_opts_file" ]]; then
vlog "Using jvm options defined in file $jvm_opts_file"
readarr extra_jvm_opts < <(readConfigFile "$jvm_opts_file")
elif [[ -n "$JVM_OPTS" && !($JVM_OPTS =~ ^@.*) ]]; then
vlog "Using jvm options defined in \$JVM_OPTS variable"
extra_jvm_opts=( $JVM_OPTS )
else
vlog "Using default jvm options"
extra_jvm_opts=( $default_jvm_opts )
fi
# since sbt 0.7 doesn't understand iflast
[[ ${#residual_args[@]} -eq 0 ]] && [[ -z "$batch" ]] && residual_args=( "shell" )
# traceLevel is 0.12+
[[ -n $trace_level ]] && setTraceLevel
[[ -n $log_level ]] && [[ $log_level != Info ]] && logLevalArg="set logLevel in Global := Level.$log_level"
# run sbt
execRunner "$java_cmd" \
"${extra_jvm_opts[@]}" \
"${java_args[@]}" \
-jar "$sbt_jar" \
"$logLevalArg" \
"${sbt_commands[@]}" \
"${residual_args[@]}"

View File

@ -1,100 +0,0 @@
{
"apiVersion": "0.5",
"swaggerVersion": "1.1",
"basePath": "http://localhost:8000",
"resourcePath": "/admin",
"apis": [
{
"path": "/admin.{format}/health",
"description": "Administrative operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Returns health report on this JVM",
"responseClass": "Health",
"nickname": "getHealth"
}
]
},
{
"path": "/admin.{format}/ping",
"description": "Administrative operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Pings service",
"responseClass": "string",
"nickname": "ping"
}
]
}
],
"models": {
"Memory": {
"required": false,
"id": "Memory",
"properties": {
"free": {
"required": true,
"uniqueItems": false,
"type": "long"
},
"max": {
"required": true,
"uniqueItems": false,
"type": "long"
},
"allocated": {
"required": true,
"uniqueItems": false,
"type": "long"
},
"used": {
"required": true,
"uniqueItems": false,
"type": "long"
},
"percentUsed": {
"required": true,
"uniqueItems": false,
"type": "double"
}
},
"uniqueItems": false,
"type": "any"
},
"Health": {
"required": false,
"id": "Health",
"properties": {
"peakThreadCount": {
"required": true,
"uniqueItems": false,
"type": "int"
},
"memory": {
"required": true,
"uniqueItems": false,
"type": "Memory"
},
"startedThreadCount": {
"required": true,
"uniqueItems": false,
"type": "long"
},
"liveThreadCount": {
"required": true,
"uniqueItems": false,
"type": "int"
},
"daemonThreadCount": {
"required": true,
"uniqueItems": false,
"type": "int"
}
},
"uniqueItems": false,
"type": "any"
}
}
}

View File

@ -1,337 +0,0 @@
{
"apiVersion": "0.5",
"swaggerVersion": "1.1",
"basePath": "http://localhost:8000",
"resourcePath": "/discovery",
"apis": [
{
"path": "/discovery.{format}/commission",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Perpare for a service to boot up and make contact",
"responseClass": "string",
"nickname": "commissionInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service from which to anticipate contact",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "serviceName",
"description": "Name of service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "buildNumber",
"description": "Build Number of service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "cluster",
"description": "Name of cluster to launch this into",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/de-commission",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Decomission an instance and remove it",
"responseClass": "string",
"nickname": "decommissionInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service to be decommissioned",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/register",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Register an instance and return its configuration",
"responseClass": "RegistrationResponse",
"nickname": "registerInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service to be registered",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/config",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Returns configuration of an instance",
"responseClass": "ConfigurationResponse",
"nickname": "getInstanceConfiguration",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service for which configuration is required",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/status",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Marks an instance's status",
"responseClass": "string",
"nickname": "updateInstanceStatus",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service which is to be marked as available",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "status",
"description": "The new status",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return base urls for a given service",
"responseClass": "List[string]",
"nickname": "getServiceInstances",
"parameters": [
{
"name": "sourceInstanceId",
"description": "InstanceId of the service which wants to call the target service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Source Instance not found"
},
{
"code": 400,
"reason": "Unknown service name specified"
}
]
}
]
},
{
"path": "/discovery.{format}/services/{status}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances running in the zone managed by this Discovery Service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstancesByStatus",
"parameters": [
{
"name": "status",
"description": "The status for which services need to be returned",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instances not found"
},
{
"code": 400,
"reason": "Unknown status specified"
}
]
}
]
}
],
"models": {
"Instance": {
"required": false,
"id": "Instance",
"properties": {
"baseUrl": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"id": {
"required": true,
"uniqueItems": false,
"type": "long"
},
"privateIp": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"buildNumber": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"lastPingedOn": {
"required": true,
"uniqueItems": false,
"type": "Date"
},
"status": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"createdAt": {
"required": true,
"uniqueItems": false,
"type": "Date"
},
"awsInstanceId": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"cluster": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"zone": {
"required": true,
"uniqueItems": false,
"type": "string"
},
"serviceName": {
"required": true,
"uniqueItems": false,
"type": "string"
}
},
"uniqueItems": false,
"type": "any"
},
"ConfigurationResponse": {
"required": false,
"id": "ConfigurationResponse",
"properties": {
"config": {
"required": true,
"uniqueItems": false,
"type": "string"
}
},
"uniqueItems": false,
"type": "any"
},
"RegistrationResponse": {
"required": false,
"id": "RegistrationResponse",
"properties": {
"config": {
"required": true,
"uniqueItems": false,
"type": "string"
}
},
"uniqueItems": false,
"type": "any"
}
}
}

View File

@ -1,403 +0,0 @@
{
"apiVersion": "0.5",
"swaggerVersion": "1.1",
"basePath": "http://localhost:9000/",
"resourcePath": "/discovery.{format}",
"models": {
"Instance": {
"id": "Instance",
"properties": {
"baseUrl": {
"type": "string"
},
"id": {
"type": "long"
},
"privateIp": {
"type": "string"
},
"buildNumber": {
"type": "string"
},
"lastPingedOn": {
"type": "Date"
},
"status": {
"type": "string"
},
"createdAt": {
"type": "Date"
},
"awsInstanceId": {
"type": "string"
},
"cluster": {
"type": "string"
},
"publicIp": {
"type": "string"
},
"zone": {
"type": "string"
},
"serviceName": {
"type": "string"
}
}
},
"ConfigurationResponse": {
"id": "ConfigurationResponse",
"properties": {
"config": {
"type": "string"
}
}
},
"RegistrationResponse": {
"id": "RegistrationResponse",
"properties": {
"config": {
"type": "string"
}
}
}
},
"apis": [
{
"path": "/discovery.{format}/commission",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Perpare for a service to boot up and make contact",
"responseClass": "string",
"nickname": "commissionInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service from which to anticipate contact",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "serviceName",
"description": "Name of service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "buildNumber",
"description": "Build Number of service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "cluster",
"description": "Name of cluster to launch this into",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/de-commission",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Decomission an instance and remove it",
"responseClass": "string",
"nickname": "decommissionInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service to be decommissioned",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/register",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Register an instance and return its configuration",
"responseClass": "RegistrationResponse",
"nickname": "registerInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service to be registered",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/instances/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances accessible to a target service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstances",
"parameters": [
{
"name": "sourceInstanceId",
"description": "InstanceId of the service which wants to call the target service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetZone",
"description": "The zone in which the target service instances should be located. Valid values are all - (all zones in the same region), same - (same zone a the source service), [zone-name] - (the name of zone for example us-west-1a, us-west-1b, us-west-1c)",
"paramType": "query",
"defaultValue": "all",
"required": false,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Source Instance not found"
},
{
"code": 400,
"reason": "Unknown service name specified"
}
]
}
]
},
{
"path": "/discovery.{format}/services/{status}/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances in the zone managed by this Discovery Service for a given status and and service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstancesByStatusAndName",
"parameters": [
{
"name": "status",
"description": "The status for which services need to be returned",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instances not found"
},
{
"code": 400,
"reason": "Unknown status specified"
}
]
}
]
},
{
"path": "/discovery.{format}/config",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Returns configuration of an instance",
"responseClass": "ConfigurationResponse",
"nickname": "getInstanceConfiguration",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service for which configuration is required",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/status",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Marks an instance's status",
"responseClass": "string",
"nickname": "updateInstanceStatus",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service which is to be marked as available",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "status",
"description": "The new status",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
]
}
]
},
{
"path": "/discovery.{format}/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return base urls accessible to a target service",
"responseClass": "List[String]",
"nickname": "getServiceInstancesUrls",
"parameters": [
{
"name": "sourceInstanceId",
"description": "InstanceId of the service which wants to call the target service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetZone",
"description": "The zone in which the target service instances should be located. Valid values are all - (all zones in the same region), same - (same zone a the source service), [zone-name] - (the name of zone for example us-west-1a, us-west-1b, us-west-1c)",
"paramType": "query",
"defaultValue": "all",
"required": false,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Source Instance not found"
},
{
"code": 400,
"reason": "Unknown service name specified"
}
]
}
]
},
{
"path": "/discovery.{format}/services/{status}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances running in the zone managed by this Discovery Service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstancesByStatus",
"parameters": [
{
"name": "status",
"description": "The status for which services need to be returned",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
],
"errorResponses": [
{
"code": 404,
"reason": "Instances not found"
},
{
"code": 400,
"reason": "Unknown status specified"
}
]
}
]
}
]
}

View File

@ -1,403 +0,0 @@
{
"apiVersion": "0.5",
"swaggerVersion": "1.1",
"basePath": "http://localhost:9000/",
"resourcePath": "/discovery.{format}",
"apis": [
{
"path": "/discovery.{format}/config",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Returns configuration of an instance",
"responseClass": "ConfigurationResponse",
"nickname": "getInstanceConfiguration",
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
],
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service for which configuration is required",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/status",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Marks an instance's status",
"responseClass": "string",
"nickname": "updateInstanceStatus",
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
],
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service which is to be marked as available",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "status",
"description": "The new status",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return base urls accessible to a target service",
"responseClass": "List[String]",
"nickname": "getServiceInstancesUrls",
"errorResponses": [
{
"code": 404,
"reason": "Source Instance not found"
},
{
"code": 400,
"reason": "Unknown service name specified"
}
],
"parameters": [
{
"name": "sourceInstanceId",
"description": "InstanceId of the service which wants to call the target service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetZone",
"description": "The zone in which the target service instances should be located. Valid values are all - (all zones in the same region), same - (same zone a the source service), [zone-name] - (the name of zone for example us-west-1a, us-west-1b, us-west-1c)",
"paramType": "query",
"defaultValue": "all",
"required": false,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/commission",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Perpare for a service to boot up and make contact",
"responseClass": "string",
"nickname": "commissionInstance",
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service from which to anticipate contact",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "serviceName",
"description": "Name of service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "buildNumber",
"description": "Build Number of service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "cluster",
"description": "Name of cluster to launch this into",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/de-commission",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Decomission an instance and remove it",
"responseClass": "string",
"nickname": "decommissionInstance",
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
],
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service to be decommissioned",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/register",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "POST",
"summary": "Register an instance and return its configuration",
"responseClass": "RegistrationResponse",
"nickname": "registerInstance",
"errorResponses": [
{
"code": 404,
"reason": "Instance not found"
}
],
"parameters": [
{
"name": "instanceId",
"description": "InstanceId of the service to be registered",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/instances/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances accessible to a target service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstances",
"errorResponses": [
{
"code": 404,
"reason": "Source Instance not found"
},
{
"code": 400,
"reason": "Unknown service name specified"
}
],
"parameters": [
{
"name": "sourceInstanceId",
"description": "InstanceId of the service which wants to call the target service",
"paramType": "query",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetZone",
"description": "The zone in which the target service instances should be located. Valid values are all - (all zones in the same region), same - (same zone a the source service), [zone-name] - (the name of zone for example us-west-1a, us-west-1b, us-west-1c)",
"paramType": "query",
"defaultValue": "all",
"required": false,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/services/{status}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances running in the zone managed by this Discovery Service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstancesByStatus",
"errorResponses": [
{
"code": 404,
"reason": "Instances not found"
},
{
"code": 400,
"reason": "Unknown status specified"
}
],
"parameters": [
{
"name": "status",
"description": "The status for which services need to be returned",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
},
{
"path": "/discovery.{format}/services/{status}/{targetServiceName}",
"description": "Discovery Service's Core Operations",
"operations": [
{
"httpMethod": "GET",
"summary": "Return instances in the zone managed by this Discovery Service for a given status and and service",
"responseClass": "List[Instance]",
"nickname": "getServiceInstancesByStatusAndName",
"errorResponses": [
{
"code": 404,
"reason": "Instances not found"
},
{
"code": 400,
"reason": "Unknown status specified"
}
],
"parameters": [
{
"name": "status",
"description": "The status for which services need to be returned",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
},
{
"name": "targetServiceName",
"description": "Name of service whose instances are needed",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"Instance": {
"id": "Instance",
"properties": {
"baseUrl": {
"type": "string"
},
"id": {
"type": "long"
},
"privateIp": {
"type": "string"
},
"buildNumber": {
"type": "string"
},
"lastPingedOn": {
"type": "Date"
},
"status": {
"type": "string"
},
"createdAt": {
"type": "Date"
},
"awsInstanceId": {
"type": "string"
},
"cluster": {
"type": "string"
},
"publicIp": {
"type": "string"
},
"zone": {
"type": "string"
},
"serviceName": {
"type": "string"
}
}
},
"ConfigurationResponse": {
"id": "ConfigurationResponse",
"properties": {
"config": {
"type": "string"
}
}
},
"RegistrationResponse": {
"id": "RegistrationResponse",
"properties": {
"config": {
"type": "string"
}
}
}
}
}

View File

@ -1,15 +0,0 @@
{
"apiVersion": "0.5",
"swaggerVersion": "1.1",
"basePath": "http://localhost:8000",
"apis": [
{
"path": "/admin.{format}",
"description": "Administrative operations"
},
{
"path": "/discovery.{format}",
"description": "Discovery Service's Core Operations"
}
]
}

View File

@ -3,6 +3,7 @@ package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#models}}
{{#model}}
public class {{classname}} {
{{#vars}}

View File

@ -1,76 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
object BasicAndroidJavaClient extends BasicAndroidJavaGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicAndroidJavaGenerator extends BasicJavaGenerator {
override def typeMapping = super.typeMapping ++ Map(
"file" -> "File")
override def importMapping = super.importMapping ++ Map(
"Set" -> "java.util.Set")
override def defaultIncludes = Set(
"Integer",
"String",
"Long",
"Short",
"Char",
"Byte",
"Float",
"Double",
"Boolean",
"AnyRef",
"Any")
// package for api invoker, error files
override def invokerPackage:Option[String] = Some("com.wordnik.client")
override def templateDir = "android-java"
// where to write generated code
override def destinationDir = "generated-code/android-java/src/main/java"
// package for models
override def modelPackage: Option[String] = Some("com.wordnik.client.model")
// package for api classes
override def apiPackage: Option[String] = Some("com.wordnik.client.api")
/**
* you should override these params for generating the pom.xml and processing
* additional params
**/
additionalParams ++= Map(
"artifactId" -> "android-client",
"artifactVersion" -> "1.0.0",
"groupId" -> "com.wordnik")
// supporting classes
override def supportingFiles = List(
("httpPatch.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "HttpPatch.java"),
("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiInvoker.java"),
("jsonUtil.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "JsonUtil.java"),
("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiException.java"),
("pom.mustache", destinationDir, "pom.xml")
)
}

View File

@ -1,209 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
object BasicCSharpGenerator extends BasicCSharpGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicCSharpGenerator extends BasicGenerator {
override def defaultIncludes = Set(
"char",
"double",
"int",
"long",
"float",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float")
/**
* We are using csharp objects instead of primitives to avoid showing default
* primitive values when the API returns missing data. For instance, having a
* {"count":0} != count is unknown. You can change this to use primitives if you
* desire, but update the default values as well or they'll be set to null in
* variable declarations.
*/
override def typeMapping = Map(
"array" -> "List",
"boolean" -> "bool?",
"string" -> "string",
"int" -> "int?",
"float" -> "float?",
"long" -> "long?",
"double" -> "double?",
"object" -> "object",
"Date" -> "DateTime?",
"date" -> "DateTime?",
"File" -> "byte[]",
"file" -> "byte[]")
// location of templates
override def templateDir = "csharp"
// where to write generated code
override def destinationDir = "generated-code/csharp/src"
override def invokerPackage: Option[String] = Some("Swagger.Client.Common")
// template used for models
modelTemplateFiles += "model.mustache" -> ".cs"
// template used for models
apiTemplateFiles += "api.mustache" -> ".cs"
override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert",
"default", "if", "package", "synchronized", "do", "goto", "private", "this", "break",
"implements", "protected", "throw", "else", "import", "public", "throws", "case",
"enum", "instanceof", "return", "transient", "catch", "extends", "try", "final",
"interface", "static", "void", "class", "finally", "strictfp", "volatile", "const",
"native", "super", "while")
// import/require statements for specific datatypes
override def importMapping = Map()
// package for models
override def modelPackage: Option[String] = Some("Swagger.Client.Model")
// package for api classes
override def apiPackage: Option[String] = Some("Swagger.Client.Api")
// file suffix
override def fileSuffix = ".cs"
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => Some(typeMapping.getOrElse(e, e.replaceAll("\\[", "<").replaceAll("\\]", ">")))
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => {
val ComplexTypeMatcher = "(.*)\\[(.*)\\].*".r
val t = e match {
case ComplexTypeMatcher(container, inner) => {
e.replaceAll(container, typeMapping.getOrElse(container.toLowerCase, container))
}
case _ => e
}
Some(typeMapping.getOrElse(t, t.replaceAll("\\[", "<").replaceAll("\\]", ">")))
}
}
}
override def toDeclaredType(dt: String): String = {
val declaredType = dt.indexOf("[") match {
case -1 => dt
case n: Int => {
if (dt.substring(0, n) == "Array")
"List" + dt.substring(n).replaceAll("\\[", "<").replaceAll("\\]", ">")
else dt.replaceAll("\\[", "<").replaceAll("\\]", ">")
}
}
typeMapping.getOrElse(declaredType, declaredType)
}
override def toDeclaration(obj: ModelProperty) = {
var declaredType = toDeclaredType(obj.`type`)
declaredType.toLowerCase match {
case "array" => declaredType = "List"
case e: String => e
}
val defaultValue = toDefaultValue(declaredType, obj)
declaredType match {
case "List" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
declaredType += "<" + toDeclaredType(inner) + ">"
}
case _ =>
}
(declaredType, defaultValue)
}
/**
* we are defaulting to null values since the codegen uses csharp objects instead of primitives
* If you change to primitives, you can put in the appropriate values (0.0f, etc).
*/
override def toDefaultValue(dataType: String, obj: ModelProperty) = {
dataType match {
case "Boolean" => "null"
case "Integer" => "null"
case "Long" => "null"
case "Float" => "null"
case "Double" => "null"
case "List" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + dataType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
"new ArrayList<" + toDeclaredType(inner) + ">" + "()"
}
case _ => "null"
}
}
override def escapeReservedWord(word: String) = {
if (reservedWords.contains(word))
throw new Exception("reserved word " + "\"" + word + "\" not allowed")
else word
}
/*override def toVarName(name: String): String = {
name match {
case _ if (reservedWords.contains(name)) => escapeReservedWord(name)
case _ => typeMapping.getOrElse(name, name)
}
capitalize(name)
}
def capitalize(s: String) = {
s(0).toUpper + s.substring(1, s.length).toLowerCase
}*/
// supporting classes
override def supportingFiles =
List(
("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiInvoker.cs"),
("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiException.cs"),
("Newtonsoft.Json.dll", "generated-code/csharp/bin", "Newtonsoft.Json.dll"),
("compile.mustache", "generated-code/csharp", "compile.bat"))
}

View File

@ -1,168 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
abstract class BasicFlashCodegen extends BasicGenerator {
override def defaultIncludes = Set(
"Date",
"String",
"Boolean",
"Number")
override def typeMapping = Map(
"boolean" -> "Boolean",
"string" -> "String",
"int" -> "Number",
"float" -> "Number",
"long" -> "Number",
"double" -> "Number")
override def packageName = "com.wordnik.client"
// location of templates
override def templateDir = "flash"
// template used for models
modelTemplateFiles += "model.mustache" -> ".as"
modelTemplateFiles += "modelList.mustache" -> "List.as"
// template used for models
apiTemplateFiles += "api.mustache" -> ".as"
// where to write generated code
override def destinationDir = "src/test/flash"
// import/require statements for specific datatypes
override def importMapping = Map()
// package for models
override def modelPackage: Option[String] = Some("com.wordnik.client.model")
// package for api classes
override def apiPackage: Option[String] = Some("com.wordnik.client.api")
// file suffix
override def fileSuffix = ".as"
override def toVarName(name: String): String = {
name.substring(0, 1).toLowerCase + name.substring(1, name.length)
}
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => Some(e)
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => {
responseClass.startsWith("List") match {
case true => {
val responseSubClass = responseClass.dropRight(1).substring(5)
typeMapping.contains(responseSubClass) match {
case true => Some("Array")
case false => Some(packageName + ".model." +
responseSubClass + "List")
}
}
case false => Some(responseClass)
}
}
}
}
override def toDeclaredType(dt: String): String = {
val declaredType = dt.indexOf("[") match {
case -1 => dt
case n: Int => {
if (dt.substring(0, n) == "Array") {
"Array"
} else if (dt.substring(0, n) == "List") {
"Array"
} else dt
}
}
typeMapping.getOrElse(declaredType, declaredType)
}
override def toDeclaration(obj: ModelProperty) = {
var declaredType = toDeclaredType(obj.`type`)
declaredType match {
case "Array" => {
declaredType = "Array"
}
case "List" => {
declaredType = "Array"
}
case e: String => e
}
val defaultValue = toDefaultValue(declaredType, obj)
declaredType match {
case "List" => "Array"
case _ =>
}
(declaredType, defaultValue)
}
override def toDefaultValue(dataType: String, obj: ModelProperty) = {
dataType match {
case "Boolean" => "false"
case "Number" => "0.0"
case "List" => "new Array()"
case "Array" => "new Array()"
case _ => "null"
}
}
def destinationRoot: String
// supporting classes
def baseSupportingFiles = List(
("ApiInvoker.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ApiInvoker.as"),
("ApiUrlHelper.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ApiUrlHelper.as"),
("ApiUserCredentials.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ApiUserCredentials.as"),
("ListWrapper.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "ListWrapper.as"),
("SwaggerApi.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "SwaggerApi.as"),
("XMLWriter.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/common", "XMLWriter.as"),
("ApiError.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/exception", "ApiError.as"),
("ApiErrorCodes.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/exception", "ApiErrorCodes.as"),
("ApiClientEvent.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/event", "ApiClientEvent.as"),
("Response.as", destinationRoot + "/src/main/flex/com/wordnik/swagger/event", "Response.as"),
("build.properties", destinationRoot, "build.properties"),
("build.xml", destinationRoot, "build.xml"),
("AirExecutorApp-app.xml", destinationRoot + "/bin", "AirExecutorApp-app.xml"),
("ASAXB-0.1.1.swc", destinationRoot + "/lib", "ASAXB-0.1.1.swc"),
("as3corelib.swc", destinationRoot + "/lib/ext", "as3corelib.swc"),
("flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-4.1.0_RC2-28-flex_3.5.0.12683.swc"),
("flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-aircilistener-4.1.0_RC2-28-3.5.0.12683.swc"),
("flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-cilistener-4.1.0_RC2-28-3.5.0.12683.swc"),
("flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc", destinationRoot + "/lib/ext", "flexunit-core-flex-4.0.0.2-sdk3.5.0.12683.swc")
)
}

View File

@ -1,394 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen._
import com.wordnik.swagger.codegen.util._
import com.wordnik.swagger.codegen.language.CodegenConfig
import com.wordnik.swagger.codegen.spec.SwaggerSpecValidator
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.model.SwaggerSerializers
import com.wordnik.swagger.codegen.spec.ValidationMessage
import com.wordnik.swagger.codegen.spec.SwaggerSpec._
import com.wordnik.swagger.util.ValidationException
import java.io.{ File, FileWriter }
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.write
import scala.io._
import scala.collection.JavaConversions._
import scala.collection.mutable.{ ListBuffer, HashMap, HashSet }
import scala.io.Source
abstract class BasicGenerator extends CodegenConfig with PathUtil {
implicit val formats = SwaggerSerializers.formats("1.2")
def packageName = "com.wordnik.client"
def templateDir = "src/main/resources/scala"
def destinationDir = "generated-code/src/main/scala"
def fileSuffix = ".scala"
override def invokerPackage: Option[String] = Some("com.wordnik.client.common")
override def modelPackage: Option[String] = Some("com.wordnik.client.model")
override def apiPackage: Option[String] = Some("com.wordnik.client.api")
var codegen = new Codegen(this)
var fileMap: Option[String] = None
@deprecated(message = "please use the generate function", since = "2.0.16")
def generateClient(args: Array[String]): Unit = {
generateClientWithoutExit(args)
System.exit(0)
}
@deprecated(message = "please use the generate function", since = "2.0.16")
def generateClientWithoutExit(args: Array[String]): Seq[File] = {
if (args.length == 0) {
throw new RuntimeException("Need url to resource listing as argument. You can also specify VM Argument -DfileMap=/path/to/folder/containing.resources.json/")
}
val host = args(0)
val apiKey = if(args.length > 1) Some(args(1)) else None
val authorization = authenticate(apiKey)
val opts = new ClientOpts()
opts.uri = host
opts.auth = authorization
opts.properties = Map("fileMap" -> sys.props("fileMap"))
generate(opts)
}
def generate(opts: ClientOpts) = {
if (opts == null) {
throw new RuntimeException("Need url to resource listing as argument. You can also specify VM Argument -DfileMap=/path/to/folder/containing.resources.json/")
}
val host = opts.uri
val authorization = opts.auth
fileMap = Option(opts.properties.getOrElse("fileMap", null))
val doc = ResourceExtractor.fetchListing(getResourcePath(host, fileMap), authorization)
additionalParams ++= opts.properties
val apis: List[ApiListing] = getApis(host, doc, authorization)
val errors = new ListBuffer[ValidationError] ++ SwaggerValidator.validate(doc)
for(api <- apis)
SwaggerValidator.validate(api, errors)
errors.filter(_.severity == SwaggerValidator.ERROR).size match {
case i: Int if i > 0 => {
println("********* Failed to read swagger json!")
errors.foreach(msg => {
println(msg)
})
Option(System.getProperty("skipErrors")) match {
case Some(str) => println("**** ignoring errors and continuing")
case None => {
val out = new StringBuilder
errors.foreach(m => out.append(m).append("\n"))
println(errors)
throw new ValidationException(400, "Failed validation", errors.toList)
}
}
}
case 0 =>
}
implicit val basePath = getBasePath(host, doc.basePath, fileMap)
new SwaggerSpecValidator(doc, apis).validate()
val allModels = new HashMap[String, Model]
val operations = extractApiOperations(apis, allModels)
val operationMap: Map[(String, String), List[(String, Operation)]] =
groupOperationsToFiles(operations)
val modelMap = prepareModelMap(allModels.toMap)
val modelFileContents = writeFiles(modelMap, modelTemplateFiles.toMap)
val modelFiles = new ListBuffer[File]()
for((filename, contents) <- modelFileContents) {
val file = new java.io.File(filename)
modelFiles += file
file.getParentFile().mkdirs
val fw = new FileWriter(filename, false)
fw.write(contents + "\n")
fw.close()
}
val apiBundle = prepareApiBundle(operationMap.toMap)
val apiInfo = writeFiles(apiBundle, apiTemplateFiles.toMap)
val apiFiles = new ListBuffer[File]()
apiInfo.map(m => {
val filename = m._1
val file = new java.io.File(filename)
apiFiles += file
file.getParentFile().mkdirs
val fw = new FileWriter(filename, false)
fw.write(m._2 + "\n")
fw.close()
println("wrote api " + filename)
})
codegen.writeSupportingClasses2(apiBundle, modelMap, doc.apiVersion) ++
modelFiles ++ apiFiles
}
/**
* applies a template to each of the models
*/
def writeFiles(models: List[Map[String, AnyRef]], templates: Map[String, String]): List[(String, String)] = {
val output = new ListBuffer[Tuple2[String, String]]
models.foreach(m => {
for ((templateFile, suffix) <- templates) {
val imports = m.getOrElse("imports", None)
val filename = m("outputDirectory").toString + File.separator + m("filename").toString + suffix
output += Tuple2(filename, generateSource(m, templateFile))
}
})
output.toList
}
def generateSource(bundle: Map[String, AnyRef], templateFile: String): String = {
val rootDir = new java.io.File(".")
val (resourcePath, (engine, template)) = Codegen.templates.getOrElseUpdate(templateFile, codegen.compileTemplate(templateFile, Some(rootDir)))
var output = engine.layout(resourcePath, template, bundle)
engine.compiler.shutdown
output
}
def getApis(host: String, doc: ResourceListing, authorization: Option[ApiKeyValue]): List[ApiListing] = {
implicit val basePath = getBasePath(host, doc.basePath, fileMap)
println("base path is " + basePath)
val apiReferences = doc.apis
if (apiReferences == null)
throw new Exception("No APIs specified by resource")
ApiExtractor.fetchApiListings(doc.swaggerVersion, basePath, apiReferences, authorization)
}
def authenticate(apiKey: Option[String]): Option[ApiKeyValue] = {
Option(System.getProperty("header")) match {
case Some(e) => {
// this is ugly and will be replaced with proper arg parsing like in ScalaAsyncClientGenerator soon
val authInfo = e.split(":")
Some(ApiKeyValue(authInfo(0), "header", authInfo(1)))
}
case _ => {
apiKey.map{ key =>
Some(ApiKeyValue("api_key", "query", key))
}.getOrElse(None)
}
}
}
def extractApiOperations(apiListings: List[ApiListing], allModels: HashMap[String, Model] )(implicit basePath:String) = {
val output = new ListBuffer[(String, String, Operation)]
apiListings.foreach(apiDescription => {
val basePath = apiDescription.basePath
val resourcePath = apiDescription.resourcePath
if(apiDescription.apis != null) {
apiDescription.apis.foreach(api => {
for ((apiPath, operation) <- ApiExtractor.extractApiOperations(basePath, api)) {
output += Tuple3(basePath, apiPath, operation)
}
})
}
output.map(op => processApiOperation(op._2, op._3))
allModels ++= CoreUtils.extractApiModels(apiDescription)
})
output.toList
}
/**
* creates a map of models and properties needed to write source
*/
def prepareModelMap(models: Map[String, Model]): List[Map[String, AnyRef]] = {
val allImports = new HashSet[String]
val outputDirectory = (destinationDir + File.separator + modelPackage.getOrElse("").replace(".", File.separator))
(for ((name, schema) <- models) yield {
if (!defaultIncludes.contains(name)) {
val modelMap: Map[String, AnyRef] = codegen.modelToMap(name, schema)
val imports = modelMap("imports").asInstanceOf[Set[Map[String, AnyRef]]]
val models: List[Map[String, Map[String, AnyRef]]] = List(Map("model" -> modelMap))
val m = new HashMap[String, AnyRef]
m += "imports" -> processImports(imports)
m += "name" -> toModelName(name)
m += "className" -> name
m += "filename" -> toModelFilename(name)
m += "apis" -> None
m += "models" -> models
m += "package" -> modelPackage
m += "invokerPackage" -> invokerPackage
m += "outputDirectory" -> outputDirectory
m += "newline" -> "\n"
m += "modelPackage" -> modelPackage
m += "modelJson" -> codegen.writeJson(schema)
m ++= additionalParams
Some(m.toMap)
}
else None
}).flatten.toList
}
def processImports(ii: Set[Map[String, AnyRef]]) = {
val allImports = new HashSet[String]()
ii.foreach(_.map(m => allImports += m._2.asInstanceOf[String]))
val imports = new ListBuffer[Map[String, String]]
val includedModels = new HashSet[String]
val importScope = modelPackage match {
case Some(s) => s + "."
case _ => ""
}
// do the mapping before removing primitives!
allImports.foreach(value => {
val model = toModelName(value.asInstanceOf[String])
includedModels.contains(model) match {
case false => {
importMapping.containsKey(model) match {
case true => {
if(!imports.flatten.map(m => m._2).toSet.contains(importMapping(model))) {
imports += Map("import" -> importMapping(model))
}
}
case false =>
}
}
case true =>
}
})
allImports --= defaultIncludes
allImports --= primitives
allImports --= containers
allImports.foreach(i => {
val model = toModelName(i)
includedModels.contains(model) match {
case false => {
importMapping.containsKey(model) match {
case true =>
case false => {
if(!imports.flatten.map(m => m._2).toSet.contains(importScope + model)){
imports += Map("import" -> (importScope + model))
}
}
}
}
case true => // no need to add the model
}
})
imports
}
def prepareApiBundle(apiMap: Map[(String, String), List[(String, Operation)]] ): List[Map[String, AnyRef]] = {
(for ((identifier, operationList) <- apiMap) yield {
val basePath = identifier._1
val name = identifier._2
val className = toApiName(name)
val allImports = new HashSet[String]
val operations = new ListBuffer[AnyRef]
val o = new ListBuffer[AnyRef]
val classNameToOperationList = new HashMap[String, ListBuffer[AnyRef]]
for ((apiPath, operation) <- operationList) {
CoreUtils.extractModelNames(operation).foreach(i => allImports += i)
}
val imports = new ListBuffer[Map[String, String]]
val includedModels = new HashSet[String]
val modelList = new ListBuffer[Map[String, AnyRef]]
val importScope = modelPackage match {
case Some(s) => s + "."
case None => ""
}
allImports --= defaultIncludes
allImports --= primitives
allImports --= containers
allImports.foreach(i => {
val model = toModelName(i)
if(!includedModels.contains(model) && !importMapping.containsKey(model)) {
if(!imports.flatten.map(m => m._2).toSet.contains(importScope + model)){
imports += Map("import" -> (importScope + model))
}
}
})
val names = new HashSet[String]
for((path, operation) <- operationList) {
val op = codegen.apiToMap(path, operation)
val nickname = op.getOrElse("nickname", op("httpMethod")).asInstanceOf[String]
var updatedNickname = nickname
if(names.contains(nickname)) {
var counter = 0
var done = false
while(!done) {
updatedNickname = nickname + "_" + className + "_" + counter
if(!names.contains(updatedNickname)) done = true
counter += 1
}
}
names += updatedNickname
o += (Map("path" -> path) ++ op ++ Map("nickname" -> updatedNickname))
}
operations += Map("operation" -> o)
val m = new HashMap[String, AnyRef]
m += "imports" -> imports
m += "baseName" -> name
m += "filename" -> toApiFilename(name)
m += "name" -> toApiName(name)
m += "classname" -> className
m += "className" -> className
m += "basePath" -> basePath
m += "package" -> apiPackage
m += "invokerPackage" -> invokerPackage
m += "operations" -> operations
m += "models" -> None
m += "outputDirectory" -> (destinationDir + File.separator + apiPackage.getOrElse("").replace(".", File.separator))
m += "newline" -> "\n"
m += "modelPackage" -> modelPackage
m ++= additionalParams
Some(m.toMap)
}).flatten.toList
}
def groupOperationsToFiles(operations: List[(String, String, Operation)]): Map[(String, String), List[(String, Operation)]] = {
val opMap = new HashMap[(String, String), ListBuffer[(String, Operation)]]
for ((basePath, apiPath, operation) <- operations) {
val className = resourceNameFromFullPath(apiPath)
val listToAddTo = opMap.getOrElse((basePath, className), {
val l = new ListBuffer[(String, Operation)]
opMap += (basePath, className) -> l
l
})
listToAddTo += Tuple2(apiPath, operation)
}
opMap.map(m => (m._1, m._2.toList)).toMap
}
}

View File

@ -1,53 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
object BasicGroovyGenerator extends BasicGroovyGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicGroovyGenerator extends BasicJavaGenerator {
// location of templates
override def templateDir = "Groovy"
// where to write generated code
override def destinationDir = "generated-code/groovy/src/main/groovy"
// template used for models
modelTemplateFiles += "model.mustache" -> ".groovy"
// template used for models
apiTemplateFiles += "api.mustache" -> ".groovy"
// package for models
override def modelPackage: Option[String] = Some("com.wordnik.client.model")
// package for api classes
override def apiPackage: Option[String] = Some("com.wordnik.client.api")
// file suffix
override def fileSuffix = ".groovy"
override def supportingFiles =
List(
("ApiUtils.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiUtils.groovy"),
("build.gradle.mustache", "generated-code/groovy", "build.gradle"))
}

View File

@ -1,251 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
object BasicJavaGenerator extends BasicJavaGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicJavaGenerator extends BasicGenerator {
override def defaultIncludes = Set(
"double",
"int",
"long",
"short",
"char",
"float",
"String",
"boolean",
"Boolean",
"Double",
"Integer",
"Long",
"Float")
/**
* We are using java objects instead of primitives to avoid showing default
* primitive values when the API returns missing data. For instance, having a
* {"count":0} != count is unknown. You can change this to use primitives if you
* desire, but update the default values as well or they'll be set to null in
* variable declarations.
*/
override def typeMapping = Map(
"Array" -> "List",
"array" -> "List",
"List" -> "List",
"boolean" -> "Boolean",
"string" -> "String",
"int" -> "Integer",
"float" -> "Float",
"number" -> "BigDecimal",
"long" -> "Long",
"short" -> "Short",
"char" -> "String",
"double" -> "Double",
"object" -> "Object",
"integer" -> "Integer")
// location of templates
override def templateDir = "Java"
// where to write generated code
override def destinationDir = "generated-code/java/src/main/java"
// template used for models
modelTemplateFiles += "model.mustache" -> ".java"
// template used for models
apiTemplateFiles += "api.mustache" -> ".java"
override def reservedWords = Set("abstract", "continue", "for", "new", "switch", "assert",
"default", "if", "package", "synchronized", "boolean", "do", "goto", "private",
"this", "break", "double", "implements", "protected", "throw", "byte", "else",
"import", "public", "throws", "case", "enum", "instanceof", "return", "transient",
"catch", "extends", "int", "short", "try", "char", "final", "interface", "static",
"void", "class", "finally", "long", "strictfp", "volatile", "const", "float",
"native", "super", "while")
// import/require statements for specific datatypes
override def importMapping = Map(
"BigDecimal" -> "java.math.BigDecimal",
"UUID" -> "java.util.UUID",
"File" -> "java.io.File",
"Date" -> "java.util.Date",
"Timestamp" -> "java.sql.Timestamp",
"Array" -> "java.util.*",
"ArrayList" -> "java.util.*",
"List" -> "java.util.*",
"Set" -> "java.util.*",
"DateTime" -> "org.joda.time.*",
"LocalDateTime" -> "org.joda.time.*",
"LocalDate" -> "org.joda.time.*",
"LocalTime" -> "org.joda.time.*"
)
// package for models
override def modelPackage: Option[String] = Some("com.wordnik.client.model")
// package for api classes
override def apiPackage: Option[String] = Some("com.wordnik.client.api")
// file suffix
override def fileSuffix = ".java"
override def toVarName(name: String): String = {
val paramName = name.replaceAll("[^a-zA-Z0-9_]","")
super.toVarName(paramName)
}
override def toApiFilename(name: String): String = {
val paramName = name.replaceAll("[^a-zA-Z0-9_]","")
super.toApiFilename(paramName)
}
override def toApiName(name: String): String = {
val paramName = name.replaceAll("[^a-zA-Z0-9_]","")
super.toApiName(paramName)
}
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => Some(typeMapping.getOrElse(e, e.replaceAll("\\[", "<").replaceAll("\\]", ">")))
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => {
val ComplexTypeMatcher = "(.*)\\[(.*)\\].*".r
val t = e match {
case ComplexTypeMatcher(container, inner) => {
e.replaceAll(container, typeMapping.getOrElse(container, container))
}
case _ => e
}
Some(typeMapping.getOrElse(t, t.replaceAll("\\[", "<").replaceAll("\\]", ">")))
}
}
}
override def toDeclaredType(dt: String): String = {
val declaredType = dt.indexOf("[") match {
case -1 => dt
case n: Int => {
if (dt.substring(0, n) == "Array")
"List" + dt.substring(n).replaceAll("\\[", "<").replaceAll("\\]", ">")
else if (dt.substring(0, n) == "Set")
"Set" + dt.substring(n).replaceAll("\\[", "<").replaceAll("\\]", ">")
else dt.replaceAll("\\[", "<").replaceAll("\\]", ">")
}
}
typeMapping.getOrElse(declaredType, declaredType)
}
override def toDeclaration(obj: ModelProperty) = {
var declaredType = toDeclaredType(obj.`type`)
declaredType match {
case "Array" => declaredType = "List"
case e: String => e
}
val defaultValue = toDefaultValue(declaredType, obj)
declaredType match {
case "List" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + declaredType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
declaredType += "<" + toDeclaredType(inner) + ">"
}
case "Set" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + declaredType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
declaredType += "<" + toDeclaredType(inner) + ">"
}
case _ =>
}
(declaredType, defaultValue)
}
/**
* you should override these params for generating the pom.xml and processing
* additional params
**/
additionalParams ++= Map(
"artifactId" -> "java-client",
"artifactVersion" -> "1.0.0",
"groupId" -> "com.wordnik")
/**
* we are defaulting to null values since the codegen uses java objects instead of primitives
* If you change to primitives, you can put in the appropriate values (0.0f, etc).
*/
override def toDefaultValue(dataType: String, obj: ModelProperty) = {
dataType match {
case "Boolean" => "null"
case "Integer" => "null"
case "Long" => "null"
case "Short" => "null"
case "Float" => "null"
case "Double" => "null"
case "List" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + dataType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
"new ArrayList<" + toDeclaredType(inner) + ">" + "()"
}
case _ => "null"
}
}
override def escapeReservedWord(word: String) = {
if (reservedWords.contains(word))
throw new Exception("reserved word " + "\"" + word + "\" not allowed")
else word
}
// supporting classes
override def supportingFiles =
List(
("apiInvoker.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiInvoker.java"),
("JsonUtil.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "JsonUtil.java"),
("apiException.mustache", destinationDir + java.io.File.separator + invokerPackage.get.replace(".", java.io.File.separator) + java.io.File.separator, "ApiException.java"),
("pom.mustache", "generated-code/java", "pom.xml"))
}

View File

@ -1,247 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
object BasicObjcGenerator extends BasicObjcGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicObjcGenerator extends BasicGenerator {
override def defaultIncludes = Set(
"bool",
"int",
"NSString",
"NSObject",
"NSArray",
"NSNumber")
override def languageSpecificPrimitives = Set(
"NSNumber",
"NSString",
"NSObject",
"bool")
override def reservedWords = Set("void", "char", "short", "int", "void", "char", "short", "int", "long", "float", "double", "signed", "unsigned", "id", "const", "volatile", "in", "out", "inout", "bycopy", "byref", "oneway", "self", "super")
def foundationClasses = Set(
"NSNumber",
"NSObject",
"NSString")
override def typeMapping = Map(
"enum" -> "NSString",
"date" -> "SWGDate",
"Date" -> "SWGDate",
"boolean" -> "NSNumber",
"string" -> "NSString",
"integer" -> "NSNumber",
"int" -> "NSNumber",
"float" -> "NSNumber",
"long" -> "NSNumber",
"double" -> "NSNumber",
"Array" -> "NSArray",
"array" -> "NSArray",
"List" -> "NSArray",
"object" -> "NSObject")
override def importMapping = Map(
"Date" -> "SWGDate")
override def toModelFilename(name: String) = "SWG" + name
// naming for the models
override def toModelName(name: String) = {
(typeMapping.keys ++
foundationClasses ++
importMapping.values ++
defaultIncludes ++
languageSpecificPrimitives
).toSet.contains(name) match {
case true => name(0).toUpper + name.substring(1)
case _ => {
"SWG" + name(0).toUpper + name.substring(1)
}
}
}
// objective c doesn't like variables starting with "new"
override def toVarName(name: String): String = {
val paramName = name.replaceAll("[^a-zA-Z0-9_]","")
if(paramName.startsWith("new") || reservedWords.contains(paramName)) {
escapeReservedWord(paramName)
}
else paramName
}
// naming for the apis
override def toApiName(name: String) = "SWG" + name(0).toUpper + name.substring(1) + "Api"
// location of templates
override def templateDir = "objc"
// template used for models
modelTemplateFiles += "model-header.mustache" -> ".h"
modelTemplateFiles += "model-body.mustache" -> ".m"
// template used for apis
apiTemplateFiles += "api-header.mustache" -> ".h"
apiTemplateFiles += "api-body.mustache" -> ".m"
// package for models
override def invokerPackage: Option[String] = None
// package for models
override def modelPackage: Option[String] = None
// package for api classes
override def apiPackage: Option[String] = None
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
typeMapping.contains(responseClass) match {
case true => Some(typeMapping(responseClass))
case false => {
responseClass match {
case "void" => None
case e: String => {
if(responseClass.toLowerCase.startsWith("array") || responseClass.toLowerCase.startsWith("list"))
Some("NSArray")
else
Some(toModelName(responseClass))
}
}
}
}
}
override def processApiMap(m: Map[String, AnyRef]): Map[String, AnyRef] = {
val mutable = scala.collection.mutable.Map() ++ m
mutable += "newline" -> "\n"
mutable.map(k => {
k._1 match {
case e: String if (e == "allParams") => {
val sp = (mutable(e)).asInstanceOf[List[_]]
sp.size match {
case i: Int if(i > 0) => mutable += "hasParams" -> "true"
case _ =>
}
}
case _ =>
}
})
mutable.toMap
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
processResponseClass(responseClass) match {
case Some("void") => Some("void")
case Some(e) => Some(e + "*")
case _ => Some(responseClass)
}
}
override def toDeclaredType(dt: String): String = {
val declaredType = dt.indexOf("[") match {
case -1 => dt
case n: Int => "NSArray"
}
val t = typeMapping.getOrElse(declaredType, declaredType)
(languageSpecificPrimitives.contains(t) && !foundationClasses.contains(t)) match {
case true => toModelName(t)
case _ => toModelName(t) + "*" // needs pointer
}
}
override def toDeclaration(obj: ModelProperty) = {
var declaredType = toDeclaredType(obj.`type`)
declaredType.toLowerCase match {
case "list" => {
declaredType = "array"
}
case e: String => e
}
val defaultValue = toDefaultValue(declaredType, obj)
declaredType match {
case "array" => {
val inner = {
obj.items match {
case Some(items) => {
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
"NSArray"
}
case "set" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
"NSArray"
}
case _ =>
}
(declaredType, defaultValue)
}
override def escapeReservedWord(word: String) = "_" + word
override def toDefaultValue(properCase: String, obj: ModelProperty) = {
properCase match {
case "boolean" => "false"
case "int" => "0"
case "long" => "0L"
case "float" => "0.0f"
case "double" => "0.0"
case "List" => {
val inner = {
obj.items match {
case Some(items) => {
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => {
println("failed on " + properCase + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
"new ArrayList<" + inner + ">" + "()"
}
case _ => "null"
}
}
}

View File

@ -1,160 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
import java.io.File
object BasicPHPGenerator extends BasicPHPGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicPHPGenerator extends BasicGenerator {
// template used for models
modelTemplateFiles += "model.mustache" -> ".php"
// template used for models
apiTemplateFiles += "api.mustache" -> ".php"
// location of templates
override def templateDir = "php"
// where to write generated code
override def destinationDir = "generated-code/php"
// package for models
override def modelPackage: Option[String] = Some("models")
// package for apis
override def apiPackage: Option[String] = Some("")
// file suffix
override def fileSuffix = ".php"
// reserved words which need special quoting
// These will all be object properties, in which context we don't need
// to worry about escaping them for PHP.
override def reservedWords = Set()
// import/require statements for specific datatypes
override def importMapping = Map()
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
typeMapping.contains(responseClass) match {
case true => Some(typeMapping(responseClass))
case false => {
responseClass match {
case "void" => None
case e: String => {
responseClass.startsWith("List") match {
case true => Some("array")
case false => Some(responseClass)
}
}
}
}
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
typeMapping.contains(responseClass) match {
case true => Some(typeMapping(responseClass))
case false => {
responseClass match {
case "void" => None
case e: String => {
responseClass.startsWith("List") match {
case true => {
val responseSubClass = responseClass.dropRight(1).substring(5)
typeMapping.contains(responseSubClass) match {
case true => Some("array[" + typeMapping(responseSubClass) + "]")
case false => Some("array[" + responseSubClass + "]")
}
}
case false => Some(responseClass)
}
}
}
}
}
}
override def typeMapping = Map(
"string" -> "string",
"str" -> "string",
"int" -> "int",
"float" -> "float",
"long" -> "int",
"double" -> "float",
"Array" -> "array",
"boolean" -> "bool",
"Date" -> "DateTime"
)
override def toDeclaredType(dt: String): String = {
val declaredType = typeMapping.getOrElse(dt, dt)
declaredType.startsWith("Array") match {
case true => {
val innerType = dt.dropRight(1).substring(6)
typeMapping.contains(innerType) match {
case true => "array[" + typeMapping(innerType) + "]"
case false => "array[" + innerType + "]"
}
}
case _ => declaredType
}
}
override def toDeclaration(obj: ModelProperty) = {
var declaredType = toDeclaredType(obj.`type`)
declaredType match {
case "Array" => declaredType = "array"
case e: String => {
e
}
}
val defaultValue = toDefaultValue(declaredType, obj)
declaredType match {
case "array" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + declaredType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
declaredType += "[" + toDeclaredType(inner) + "]"
"array"
}
case _ =>
}
(declaredType, defaultValue)
}
// supporting classes
override def supportingFiles = List(
("Swagger.mustache", destinationDir + File.separator + apiPackage.get,
"Swagger.php")
)
}

View File

@ -1,45 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import java.io.File
object BasicPython3Generator extends BasicPython3Generator {
def main(args: Array[String]) = generateClient(args)
}
class BasicPython3Generator extends BasicPythonGenerator {
// location of templates
override def templateDir = "python3"
// where to write generated code
override def destinationDir = "generated-code/python3"
// Python3 erases int/long distinction
override def typeMapping = Map(
"string" -> "str",
"int" -> "int",
"float" -> "float",
"long" -> "int",
"double" -> "float",
"Array" -> "list",
"array" -> "list",
"boolean" -> "bool",
"Date" -> "datetime"
)
}

View File

@ -1,165 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
import java.io.File
object BasicPythonGenerator extends BasicPythonGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicPythonGenerator extends BasicGenerator {
// template used for models
modelTemplateFiles += "model.mustache" -> ".py"
// template used for models
apiTemplateFiles += "api.mustache" -> ".py"
// location of templates
override def templateDir = "python"
// where to write generated code
override def destinationDir = "generated-code/python"
// package for models
override def modelPackage: Option[String] = Some("models")
// package for apis
override def apiPackage = None
// file suffix
override def fileSuffix = ".py"
// reserved words which need special quoting
// These will all be object properties, in which context we don't need
// to worry about escaping them for Python.
override def reservedWords = Set()
// import/require statements for specific datatypes
override def importMapping = Map()
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
typeMapping.contains(responseClass) match {
case true => Some(typeMapping(responseClass))
case false => {
responseClass match {
case "void" => None
case e: String => {
responseClass.startsWith("List") match {
case true => Some("list")
case false => Some(responseClass)
}
}
}
}
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
typeMapping.contains(responseClass) match {
case true => Some(typeMapping(responseClass))
case false => {
responseClass match {
case "void" => None
case e: String => {
responseClass.startsWith("List") match {
case true => {
val responseSubClass = responseClass.dropRight(1).substring(5)
typeMapping.contains(responseSubClass) match {
case true => Some("list[" + typeMapping(responseSubClass) + "]")
case false => Some("list[" + responseSubClass + "]")
}
}
case false => Some(responseClass)
}
}
}
}
}
}
override def typeMapping = Map(
"float" -> "float",
"long" -> "long",
"double" -> "float",
"Array" -> "list",
"boolean" -> "bool",
"string" -> "str",
"Date" -> "datetime"
)
override def toDeclaredType(dt: String): String = {
val declaredType = typeMapping.getOrElse(dt, dt)
declaredType.startsWith("Array") match {
case true => {
val innerType = dt.dropRight(1).substring(6)
typeMapping.contains(innerType) match {
case true => "list[" + typeMapping(innerType) + "]"
case false => "list[" + innerType + "]"
}
}
case _ => {
declaredType
}
}
}
override def toDeclaration(obj: ModelProperty) = {
var declaredType = toDeclaredType(obj.`type`)
declaredType match {
case "Array" => declaredType = "list"
case e: String => {
e
}
}
val defaultValue = toDefaultValue(declaredType, obj)
declaredType match {
case "list" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + declaredType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
declaredType += "[" + toDeclaredType(inner) + "]"
"list"
}
case _ =>
}
(declaredType, defaultValue)
}
// escape keywords
override def escapeReservedWord(word: String) = "`" + word + "`"
// supporting classes
override def supportingFiles = List(
("__init__.mustache", destinationDir, "__init__.py"),
("swagger.mustache", destinationDir + File.separator + apiPackage.getOrElse(""),
"swagger.py"),
("__init__.mustache", destinationDir + File.separator +
modelPackage.getOrElse(""), "__init__.py"))
}

View File

@ -1,117 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
import java.io.File
object BasicRubyGenerator extends BasicRubyGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicRubyGenerator extends BasicGenerator {
override def apiPackage: Option[String] = Some("lib")
// location of templates
override def templateDir = "ruby"
// template used for models
modelTemplateFiles += "model.mustache" -> ".rb"
// template used for models
apiTemplateFiles += "api.mustache" -> ".rb"
// where to write generated code
override def destinationDir = "generated-code/ruby"
// file suffix
override def fileSuffix = ".rb"
// package for models
override def modelPackage: Option[String] = Some("models")
// response classes
override def processResponseClass(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => Some(e)
}
}
override def toApiName(name: String) = {
var fixedName = name.replaceAll("(\\{|\\})","")
fixedName(0).toUpper + fixedName.substring(1) + "_api"
}
override def toModelFilename(name: String) = name.toLowerCase.replaceAll("(\\{|\\})","")
override def toApiFilename(name: String) = name.toLowerCase.replaceAll("(\\{|\\})","") + "_api"
override def toVarName(name: String): String = toUnderscore(name)
override def toMethodName(name: String): String = toUnderscore(name)
def toUnderscore(name: String): String = {
val sb = new StringBuilder
for ((char) <- super.toVarName(name)) {
if (char.isUpper) sb.append("_").append(char.toLower)
else sb.append(char)
}
sb.toString
}
override def toDeclaration(obj: ModelProperty) = {
var dataType = obj.`type`(0).toUpper + obj.`type`.substring(1)
dataType match {
case "Array" => dataType = "List"
case e: String => e
}
val defaultValue = toDefaultValue(dataType, obj)
dataType match {
case "List" => {
val inner = {
obj.items match {
case Some(items) => {
if(items.ref != null)
items.ref
else
items.`type`
}
case _ => {
println("failed on " + dataType + ", " + obj)
throw new Exception("no inner type defined")
}
}
}
dataType = "java.util.List[" + inner + "]"
}
case _ =>
}
(dataType, defaultValue)
}
// supporting classes
override def supportingFiles = List(
("monkey.mustache", destinationDir + File.separator + apiPackage.get, "monkey.rb"),
("swagger.mustache", destinationDir + File.separator + apiPackage.get, "swagger.rb"),
("swagger" + File.separator + "configuration.mustache", destinationDir + File.separator + apiPackage.get, "swagger" + File.separator + "configuration.rb"),
("swagger" + File.separator + "response.mustache", destinationDir + File.separator + apiPackage.get, "swagger" + File.separator + "response.rb"),
("swagger" + File.separator + "version.mustache", destinationDir + File.separator + apiPackage.get, "swagger" + File.separator + "version.rb"),
("swagger" + File.separator + "request.mustache", destinationDir + File.separator + apiPackage.get, "swagger" + File.separator + "request.rb"))
}

View File

@ -1,221 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
object BasicScalaGenerator extends BasicScalaGenerator {
def main(args: Array[String]) = generateClient(args)
}
class BasicScalaGenerator extends BasicGenerator {
override def defaultIncludes = Set(
"Int",
"String",
"Long",
"Short",
"Char",
"Byte",
"Float",
"Double",
"Boolean",
"AnyRef",
"Any")
override def typeMapping = Map(
"array" -> "List",
"set" -> "Set",
"boolean" -> "Boolean",
"string" -> "String",
"int" -> "Int",
"long" -> "Long",
"float" -> "Float",
"byte" -> "Byte",
"short" -> "Short",
"char" -> "Char",
"long" -> "Long",
"double" -> "Double",
"object" -> "Any",
"file" -> "File")
// template used for models
modelTemplateFiles += "model.mustache" -> ".scala"
// template used for models
apiTemplateFiles += "api.mustache" -> ".scala"
// location of templates
override def templateDir = "scala"
// where to write generated code
override def destinationDir = "generated-code/scala/src/main/scala"
// reserved words which need special quoting
override def reservedWords =
Set(
"abstract",
"case",
"catch",
"class",
"def",
"do",
"else",
"extends",
"false",
"final",
"finally",
"for",
"forSome",
"if",
"implicit",
"import",
"lazy",
"match",
"new",
"null",
"object",
"override",
"package",
"private",
"protected",
"return",
"sealed",
"super",
"this",
"throw",
"trait",
"try",
"true",
"type",
"val",
"var",
"while",
"with",
"yield")
// import/require statements for specific datatypes
override def importMapping = Map(
"Date" -> "java.util.Date",
"File" -> "java.io.File"
)
// package for models
override def modelPackage: Option[String] = Some("com.wordnik.client.model")
// package for api classes
override def apiPackage: Option[String] = Some("com.wordnik.client.api")
// response classes--if you don't want a response class, override and set to None
override def processResponseClass(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => Some(typeMapping.getOrElse(e, e))
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => {
val ComplexTypeMatcher = "(.*)\\[(.*)\\].*".r
val t = e match {
case ComplexTypeMatcher(container, inner) => {
e.replaceAll(container, typeMapping.getOrElse(container.toLowerCase, container))
}
case _ => e
}
Some(typeMapping.getOrElse(t, t))
}
}
}
override def toDeclaredType(dt: String): String = {
val declaredType = dt.indexOf("[") match {
case -1 => dt
case n: Int => {
if (dt.substring(0, n) == "Array")
"List" + dt.substring(n)
else if (dt.substring(0, n) == "Set")
"Set" + dt.substring(n)
else dt
}
}
typeMapping.getOrElse(declaredType, declaredType)
}
override def toDeclaration(obj: ModelProperty): (String, String) = {
obj.`type` match {
case "Array" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
val e = "List[%s]".format(toDeclaredType(inner))
(e, toDefaultValue(inner, obj))
}
case "List" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
val e = "List[%s]".format(toDeclaredType(inner))
(e, toDefaultValue(inner, obj))
}
case "Set" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
val e = "Set[%s]".format(toDeclaredType(inner))
(e, toDefaultValue(inner, obj))
}
case e: String => (toDeclaredType(e), toDefaultValue(e, obj))
}
}
// escape keywords
override def escapeReservedWord(word: String) = "`" + word + "`"
/**
* you should override these params for generating the pom.xml and processing
* additional params
**/
additionalParams ++= Map(
"artifactId" -> "scala-client",
"artifactVersion" -> "1.0.0",
"groupId" -> "com.wordnik")
// supporting classes
override def supportingFiles = List(
("apiInvoker.mustache", destinationDir + "/com/wordnik/client", "ApiInvoker.scala"),
("pom.mustache", "generated-code/scala", "pom.xml"))
}

View File

@ -1,548 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.util.CoreUtils
import com.wordnik.swagger.codegen.language.CodegenConfig
import com.wordnik.swagger.codegen.spec.SwaggerSpec._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.write
import org.fusesource.scalate._
import org.fusesource.scalate.layout.DefaultLayoutStrategy
import org.fusesource.scalate.mustache._
import org.fusesource.scalate.support.ScalaCompiler
import java.io.{ File, FileWriter, InputStream }
import org.apache.commons.io.FileUtils
import scala.io.Source
import scala.collection.mutable.{ HashMap, ListBuffer, HashSet }
import scala.collection.JavaConversions._
object Codegen {
val templates = new HashMap[String, (String, (TemplateEngine, Template))]
}
class Codegen(config: CodegenConfig) {
implicit val formats = SwaggerSerializers.formats("1.2")
def compileTemplate(templateFile: String, rootDir: Option[File] = None, engine: Option[TemplateEngine] = None): (String, (TemplateEngine, Template)) = {
val engine = new TemplateEngine(rootDir orElse Some(new File(".")))
val srcName = config.templateDir + "/" + templateFile
val srcStream = {
getClass.getClassLoader.getResourceAsStream(srcName) match {
case is: java.io.InputStream => is
case _ => {
val f = new java.io.File(srcName)
if (!f.exists) throw new Exception("Missing template: " + srcName)
else new java.io.FileInputStream(f)
}
}
}
val template = engine.compile(
TemplateSource.fromText(config.templateDir + File.separator + templateFile,
Source.fromInputStream(srcStream).mkString))
(srcName, engine -> template)
}
def rawAllowableValuesToString(v: AllowableValues) = {
v match {
case av: AllowableListValues => {
av
}
case av: AllowableRangeValues => {
av
}
case _ => None
}
}
def allowableValuesToString(v: AllowableValues) = {
v match {
case av: AllowableListValues => {
Some(av.values.mkString("LIST[", ",", "]"))
}
case av: AllowableRangeValues => {
Some("RANGE[" + av.min + "," + av.max + "]")
}
case _ => None
}
}
def apiToMap(path: String, operation: Operation): Map[String, AnyRef] = {
var bodyParam: Option[String] = None
var queryParams = new ListBuffer[AnyRef]
val pathParams = new ListBuffer[AnyRef]
val headerParams = new ListBuffer[AnyRef]
val bodyParams = new ListBuffer[AnyRef]
val formParams = new ListBuffer[AnyRef]
var paramList = new ListBuffer[HashMap[String, AnyRef]]
var errorList = new ListBuffer[HashMap[String, AnyRef]]
var bodyParamRequired: Option[String] = Some("true")
if (operation.responseMessages != null) {
operation.responseMessages.foreach(param => {
val params = new HashMap[String, AnyRef]
params += "code" -> param.code.toString()
params += "reason" -> param.message
if (!param.responseModel.isEmpty)
params += "responseModel" -> param.responseModel
params += "hasMore" -> "true"
errorList += params
})
}
if (operation.parameters != null) {
operation.parameters.foreach(param => {
val params = new HashMap[String, AnyRef]
params += (param.paramType + "Parameter") -> "true"
params += "type" -> param.paramType
params += "defaultValue" -> config.toDefaultValue(param.dataType, param.defaultValue.getOrElse(""))
params += "swaggerDataType" -> param.dataType
params += "description" -> param.description
params += "hasMore" -> "true"
params += "allowMultiple" -> param.allowMultiple.toString
if(param.dataType == "File") params += "isFile" -> "true"
else params += "notFile" -> "true"
val u = param.dataType.indexOf("[") match {
case -1 => config.toDeclaredType(param.dataType)
case n: Int => {
val ComplexTypeMatcher = "(.*)\\[(.*)\\].*".r
val ComplexTypeMatcher(container, basePart) = param.dataType
config.toDeclaredType(container + "[" + config.toDeclaredType(basePart) + "]")
}
}
params += "dataType" -> u
params += "getter" -> config.toGetter(param.name, u)
params += "setter" -> config.toSetter(param.name, u)
param.allowableValues match {
case a: AllowableValues => params += "allowableValues" -> allowableValuesToString(a)
case _ =>
}
if (param.required) {
params += "required" -> "true"
} else {
params += "optional" -> "true"
}
param.paramType match {
case "body" => {
params += "paramName" -> "body"
params += "baseName" -> "body"
if (!param.required) {
bodyParamRequired = None
}
bodyParam = Some("body")
bodyParams += params.clone
}
case "path" => {
params += "paramName" -> config.toVarName(param.name)
params += "baseName" -> param.name
params += "required" -> "true"
params -= "optional"
pathParams += params.clone
}
case "query" => {
params += "paramName" -> config.toVarName(param.name)
params += "baseName" -> param.name
queryParams += params.clone
}
case "header" => {
params += "paramName" -> config.toVarName(param.name)
params += "baseName" -> param.name
headerParams += params.clone
}
case "form" => {
params += "paramName" -> config.toVarName(param.name)
params += "baseName" -> param.name
formParams += params.clone
}
case x @ _ => throw new Exception("Unknown parameter type: " + x)
}
paramList += params
})
}
val requiredParams = new ListBuffer[HashMap[String, AnyRef]]
paramList.filter(p => p.contains("required") && p("required") == "true").foreach(param => {
requiredParams += (param.clone += "hasMore" -> "true")
})
requiredParams.size match {
case 0 =>
case _ => requiredParams.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
headerParams.size match {
case 0 =>
case _ => headerParams.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
queryParams.size match {
case 0 =>
case _ => queryParams.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
pathParams.size match {
case 0 =>
case _ => pathParams.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
errorList.size match{
case 0 =>
case _ => errorList.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
val sp = {
val lb = new ListBuffer[AnyRef]
paramList.foreach(i => {
i += "secondaryParam" -> "true"
i("defaultValue") match {
case Some(e) =>
case None => lb += i
}
})
paramList.foreach(i => {
i("defaultValue") match {
case Some(e) => lb += i
case None =>
}
})
lb.toList
}
paramList.size match {
case 0 =>
case _ => {
sp.head.asInstanceOf[HashMap[String, String]] -= "secondaryParam"
sp.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
}
val writeMethods = Set("POST", "PUT", "PATCH")
val properties =
HashMap[String, AnyRef](
"path" -> path,
"nickname" -> config.toMethodName(operation.nickname),
"summary" -> operation.summary,
"notes" -> operation.notes,
"deprecated" -> operation.`deprecated`,
"bodyParam" -> bodyParam,
"bodyParamRequired" -> bodyParamRequired,
"emptyBodyParam" -> (if (writeMethods contains operation.method.toUpperCase) "{}" else ""),
"allParams" -> sp,
"bodyParams" -> bodyParams.toList,
"pathParams" -> pathParams.toList,
"queryParams" -> queryParams.toList,
"headerParams" -> headerParams.toList,
"formParams" -> formParams.toList,
"requiredParams" -> requiredParams.toList,
"errorList" -> errorList,
"httpMethod" -> operation.method.toUpperCase,
"httpMethodLowerCase" -> operation.method.toLowerCase,
operation.method.toLowerCase -> "true")
if (0 < operation.consumes.length) {
val o = new ListBuffer[Map[String, String]]
for(i <- 0 until operation.consumes.length) {
val m = new HashMap[String, String]
if(i < (operation.consumes.length - 1))
m += "hasMore" -> "true"
m += "mediaType" -> operation.consumes(i)
o += m.toMap
}
properties += "consumes" -> o.toList
} else {
properties += "consumes" -> List(Map("mediaType" -> "application/json"))
}
if (0 < operation.produces.length) {
val o = new ListBuffer[Map[String, String]]
for(i <- 0 until operation.produces.length) {
val m = new HashMap[String, String]
if((i + 1) < operation.produces.length)
m += "hasMore" -> "true"
m += "mediaType" -> operation.produces(i)
o += m.toMap
}
properties += "produces" -> o.toList
} else {
properties += "produces" -> List(Map("mediaType" -> "application/json"))
}
if (requiredParams.size > 0) properties += "requiredParamCount" -> requiredParams.size.toString
operation.responseClass.indexOf("[") match {
case -1 => {
val baseType = operation.responseClass
properties += "returnType" -> config.processResponseDeclaration(baseType)
properties += "returnBaseType" -> config.processResponseClass(baseType)
properties += "returnSimpleType" -> "true"
properties += "returnTypeIsPrimitive" -> {
(config.languageSpecificPrimitives.contains(baseType) || primitives.contains(baseType)) match {
case true => Some("true")
case _ => None
}
}
}
case n: Int => {
val ComplexTypeMatcher = ".*\\[(.*)\\].*".r
val ComplexTypeMatcher(basePart) = operation.responseClass
properties += "returnType" -> config.processResponseDeclaration(operation.responseClass.replaceAll(basePart, config.processResponseClass(basePart).get))
properties += "returnContainer" -> config.processResponseClass(operation.responseClass.substring(0, n))
properties += "returnBaseType" -> config.processResponseClass(basePart)
properties += "returnTypeIsPrimitive" -> {
(config.languageSpecificPrimitives.contains(basePart) || primitives.contains(basePart)) match {
case true => Some("true")
case _ => None
}
}
}
}
config.processApiMap(properties.toMap)
}
def modelToMap(className: String, model: Model): Map[String, AnyRef] = {
val data: HashMap[String, AnyRef] =
HashMap(
"classname" -> config.toModelName(className),
"className" -> config.toModelName(className),
"classVarName" -> config.toVarName(className), // suggested name of object created from this class
"modelPackage" -> config.modelPackage,
"description" -> model.description,
"modelJson" -> writeJson(model),
"newline" -> "\n")
val l = new ListBuffer[AnyRef]
val imports = new HashSet[AnyRef]
model.properties.map(prop => {
val propertyDocSchema = prop._2
val dt = propertyDocSchema.`type`
var baseType = dt
// import the object inside the container
if (propertyDocSchema.items != null && !config.typeMapping.contains(dt)) {
// import the container
imports += Map("import" -> dt)
propertyDocSchema.items match {
case Some(items) => baseType = items.ref.getOrElse(items.`type`)
case _ =>
}
}
baseType = config.typeMapping.contains(baseType) match {
case true => config.typeMapping(baseType)
case false => {
// imports += Map("import" -> config.toDeclaredType(baseType))
baseType
}
}
(config.defaultIncludes ++ config.languageSpecificPrimitives).toSet.contains(baseType) match {
case true =>
case _ => {
imports += Map("import" -> baseType)
}
}
val isList = (if (isListType(propertyDocSchema.`type`)) true else None)
val isMap = (if (isMapType(propertyDocSchema.`type`)) true else None)
val isNotContainer = if (!isListType(propertyDocSchema.`type`) && !isMapType(propertyDocSchema.`type`)) true else None
val isContainer = if (isListType(propertyDocSchema.`type`) || isMapType(propertyDocSchema.`type`)) true else None
val properties =
HashMap(
"name" -> config.toVarName(prop._1),
"nameSingular" -> {
val name = config.toVarName(prop._1)
if (name.endsWith("s") && name.length > 1) name.substring(0, name.length - 1) else name
},
"baseType" -> {
if (primitives.contains(baseType))
baseType
else
config.modelPackage match {
case Some(p) => p + "." + baseType
case _ => baseType
}
},
"baseTypeVarName" -> config.toVarName(baseType),
"baseName" -> prop._1,
"datatype" -> config.toDeclaration(propertyDocSchema)._1,
"defaultValue" -> config.toDeclaration(propertyDocSchema)._2,
"description" -> propertyDocSchema.description,
"notes" -> propertyDocSchema.description,
"allowableValues" -> rawAllowableValuesToString(propertyDocSchema.allowableValues),
(if(propertyDocSchema.required) "required" else "isNotRequired") -> "true",
"getter" -> config.toGetter(prop._1, config.toDeclaration(propertyDocSchema)._1),
"setter" -> config.toSetter(prop._1, config.toDeclaration(propertyDocSchema)._1),
"isList" -> isList,
"isMap" -> isMap,
"isContainer" -> isContainer,
"isNotContainer" -> isNotContainer,
"hasMore" -> "true")
(config.languageSpecificPrimitives.contains(baseType) || primitives.contains(baseType)) match {
case true => properties += "isPrimitiveType" -> "true"
case _ => properties += "complexType" -> config.toModelName(baseType)
}
l += properties
})
if(l.size > 0) {
val last = l.last.asInstanceOf[HashMap[String, String]]
last.remove("hasMore")
}
data += "vars" -> l
data += "imports" -> imports.toSet
config.processModelMap(data.toMap)
}
/**
* gets an input stream from resource or file
*/
def getInputStream(path: String): InputStream = {
getClass.getClassLoader.getResourceAsStream(path) match {
case is: InputStream => is
case _ => new java.io.FileInputStream(path)
}
}
def writeJson(m: AnyRef): String = {
Option(System.getProperty("modelFormat")) match {
case Some(e) if e =="1.1" => write1_1(m)
case _ => pretty(render(parse(write(m))))
}
}
def write1_1(m: AnyRef): String = {
implicit val formats = SwaggerSerializers.formats("1.1")
write(m)
}
def writeSupportingClasses2(
apiBundle: List[Map[String, AnyRef]],
modelsMap: List[Map[String, AnyRef]],
apiVersion: String): Seq[File] = {
val b = new HashMap[String, HashMap[String, AnyRef]]
modelsMap.foreach(m => {
if(m.contains("models")) {
val f = m("models").asInstanceOf[List[Map[String, AnyRef]]]
f.foreach(g => {
val e = new HashMap[String, AnyRef]
val model = g("model").asInstanceOf[Map[String, AnyRef]]
e ++= model
e += "hasMoreModels" -> "true"
b += model("classVarName").toString -> e
})
}
})
val models = new ListBuffer[HashMap[String, AnyRef]]
val keys = b.keys
var count = 0
b.values.foreach(v => {
models += v
count += 1
if(count != keys.size) {
v += "hasMoreModels" -> "true"
}
else {
v.remove("hasMoreModels")
}
})
val f = Map("model" -> models)
val rootDir: Option[File] = Some(new File("."))
val engine = new TemplateEngine(rootDir orElse Some(new File(".")))
val data = Map(
"invokerPackage" -> config.invokerPackage,
"package" -> config.packageName,
"modelPackage" -> config.modelPackage,
"apiPackage" -> config.apiPackage,
"apiInfo" -> Map("apis" -> apiBundle),
"models" -> f,
"apiVersion" -> apiVersion) ++ config.additionalParams
val outputFiles = config.supportingFiles map { file =>
val supportingFile = file._1
val outputDir = file._2
val destFile = file._3
val outputFile = new File(outputDir + File.separator + destFile)
val outputFolder = outputFile.getParent
new File(outputFolder).mkdirs
if (supportingFile.endsWith(".mustache")) {
val output = {
val (resourceName, (_, template)) = compileTemplate(supportingFile, rootDir, Some(engine))
engine.layout(resourceName, template, data.toMap)
}
val fw = new FileWriter(outputFile, false)
fw.write(output + "\n")
fw.close()
println("wrote " + outputFile.getPath())
} else {
val file = new File(config.templateDir + File.separator + supportingFile)
if (file.isDirectory()) {
// copy the whole directory
FileUtils.copyDirectory(file, new File(outputDir))
println("copied directory " + supportingFile)
} else {
val is = getInputStream(config.templateDir + File.separator + supportingFile)
val parentDir = outputFile.getParentFile()
if (parentDir != null && !parentDir.exists) {
println("making directory: " + parentDir.toString + ": " + parentDir.mkdirs)
}
FileUtils.copyInputStreamToFile(is, outputFile)
println("copied " + outputFile.getPath())
is.close
}
}
outputFile
}
//a shutdown method will be added to scalate in an upcoming release
engine.compiler.shutdown()
outputFiles
}
protected def isListType(dt: String) = isCollectionType(dt, "List") || isCollectionType(dt, "Array") || isCollectionType(dt, "Set")
protected def isMapType(dt: String) = isCollectionType(dt, "Map")
protected def isCollectionType(dt: String, str: String) = {
if (dt.equals(str))
true
else
dt.indexOf("[") match {
case -1 => false
case n: Int => {
if (dt.substring(0, n) == str) {
true
} else false
}
}
}
}

View File

@ -1,63 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
trait PathUtil {
def getResourcePath(host: String, fileMap: Option[String] = None) = {
fileMap match {
case Some(s) => s
case _ => host
}
}
def getBasePath(host: String, basePath: String, fileMap: Option[String] = None) = {
fileMap match {
case Some(s) => {
// return the parent folder
val f = new java.io.File(s)
f.getParent
}
case _ => {
if(basePath != "") basePath
else host
}
}
}
def toModelName(name: String) = {
if(name.length > 0)
name(0).toUpper + name.substring(1)
else "MISSING MODEL NAME"
}
def toApiName(name: String) = {
name.replaceAll("\\{","").replaceAll("\\}", "") match {
case s: String if(s.length > 0) => s(0).toUpper + s.substring(1) + "Api"
case _ => "Api"
}
}
def nameFromPath(apiPath: String) = {
apiPath.split("/")(1).split("\\.")(0).replaceAll("/", "")
}
def apiNameFromPath(apiPath: String) = toApiName(nameFromPath(apiPath))
def resourceNameFromFullPath(apiPath: String) = {
apiPath.split("/")(1).split("\\.")(0).replaceAll("/", "")
}
}

View File

@ -1,508 +0,0 @@
package com.wordnik.swagger.codegen
import scala.collection.mutable
import java.io.{File, FileWriter}
import com.wordnik.swagger.codegen.model._
import scala.collection.mutable.{HashMap, ListBuffer}
import language.CodegenConfig
import scala.io.Source
import org.json4s.jackson.Serialization._
import org.fusesource.scalate.{Template, TemplateSource, TemplateEngine}
import org.apache.commons.io.FileUtils
import com.wordnik.swagger.codegen.util.{CoreUtils, ApiExtractor, ResourceExtractor}
import com.wordnik.swagger.codegen.spec.SwaggerSpecValidator
import mojolly.inflector.InflectorImports._
import org.rogach.scallop.{ScallopConf, Scallop}
import scala.annotation.switch
import scala.collection.JavaConverters._
case class SwaggerApi(
clientName: String,
resourceUrl: String,
packageName: String,
apiTemplates: Map[String, String] = Map("api.mustache" -> ".scala"),
modelTemplates: Map[String, String] = Map("model.mustache" -> ".scala"),
apiKey: Option[String] = None,
baseUrl: Option[String] = None,
excludedApis: Set[String] = Set.empty,
excludedModels: Set[String] = Set.empty,
excludedModelPackages: Set[String] = Set.empty,
defaultImports: Map[String, String] = Map.empty)
case class SwaggerGenConfig(
api: SwaggerApi,
templateDir: File,
codeDir: File,
projectRoot: File,
defaultIncludes: Set[String] = Set.empty,
typeMapping: Map[String, String] = Map.empty,
defaultImports: Map[String, String] = Map.empty,
excludedModelPackages: Set[String] = Set.empty)
object AsycnClientGeneratorConf {
val appBanner: String = """
|
|
| .--.--.
| / / '.
|| : /`. / .---. __ ,-.
|; | |--` /. ./| ,----._,. ,----._,. ,' ,'/ /|
|| : ;_ .-'-. ' | ,--.--. / / ' // / ' / ,---. ' | |' |
| \ \ `. /___/ \: |/ \| : | : | / \| | ,'
| `----. \.-'.. ' ' .--. .-. | | .\ | | .\ ./ / ' : /
| __ \ \ /___/ \: '\__\/: . . ; '; . ; '; . ' / | | '
| / /`--' . \ ' .\ ," .--.; ' . . ' . . ' ; /; : |
|'--'. / \ \ ' \ / / ,. |`---`-'| |`---`-'| ' | / | , ;
| `--'---' \ \ |--; : .' .'__/\_: |.'__/\_: | : |---'
| \ \ | | , .-.| : :| : :\ \ /
| '---" `--`---' \ \ / \ \ / `----'
| `--`-' `--`-'
|
| Swagger Codegen, Reverb Technologies Inc. (c) 2009-2013
| For more info, visit: https://developers.helloreverb.com/swagger/
""".stripMargin
}
class AsycnClientGeneratorConf(arguments: Seq[String]) extends ScallopConf(arguments) {
val name = opt[String](required = true, descr = "The name of the generated client.")
val `package` = opt[String](default = Some("com.wordnik.swagger.client.async"), descr = "The package for the generated code.")
val resourceUrl = trailArg[String](descr = "The url to use for fetching the swagger spec from. This can be a http(s) url or a file path.")
val baseUrl = opt[String](descr = "The url to use when you want to override the base url provided by the resource url json.")
val apiKey = opt[String](required = false, descr = "An optional api key to use when calling the swagger api")
val templateDir = opt[String](descr = "The directory that contains the templates for use in this generator", default = Some("asyncscala"))
val codeDir = opt[String](descr = "The directory to use as base for generating code files, this will contain the generated scala files.", default = Some("src/main/scala"), hidden = true)
val projectRoot = opt[String](descr = "The directory to use as project dir, this will receive the build files (*.sbt, *.pom)", default = Some("."))
mainOptions = Seq(resourceUrl, name)
banner("""
|Usage: scala-async.sh [OPTION] spec-url
|
|The scala-async tool generates a swagger api client, using async-http-client
|and stdlib futures.
|
|Options:
|
""".stripMargin)
footer("\nFor more information, visit https://developers.helloreverb.com/swagger/")
}
object ScalaAsyncClientGenerator extends App {
val appBanner: String = AsycnClientGeneratorConf.appBanner
val opts = new AsycnClientGeneratorConf(if (args.nonEmpty) args else Array("--help"))
val rootDir = new File(opts.projectRoot())
val codeDir = {
val cd = opts.codeDir()
if (cd.startsWith("/")) new File(cd)
else new File(rootDir, cd)
}
val resUrl = {
val r = opts.resourceUrl()
if (!r.startsWith("http") && !r.startsWith("file")) sys.props("fileMap") = r
r
}
val baseUrl = opts.baseUrl.get
val cfg = SwaggerGenConfig(
api = SwaggerApi(opts.name(), resUrl, opts.`package`(), apiKey = opts.apiKey.get, baseUrl = baseUrl),
templateDir = new File(opts.templateDir()),
codeDir = new File(rootDir, opts.codeDir()),
projectRoot = rootDir
)
val generator = new ScalaAsyncClientGenerator(cfg)
val clientOpts = new ClientOpts()
val props = new HashMap[String, String]
if(resUrl.startsWith("http"))
clientOpts.uri = resUrl
else
props += "fileMap" -> resUrl
props += "clientName" -> cfg.api.clientName.underscore.pascalize
clientOpts.properties = props.toMap.asJava
println(appBanner)
generator.generate(clientOpts)
}
class AsyncClientCodegen(clientName: String, config: CodegenConfig, rootDir: Option[File] = None) extends Codegen(config) {
/*
override def writeSupportingClasses(apis: Map[(String, String), List[(String, Operation)]],
models: Map[String, Model], apiVersion: String): Seq[File] = {
def apiListF(apis: Map[(String, String), List[(String, Operation)]]): List[Map[String, AnyRef]] = {
val apiList = new ListBuffer[Map[String, AnyRef]]
apis.map(a => {
apiList += Map(
"name" -> a._1._2,
"filename" -> config.toApiFilename(a._1._2),
"className" -> config.toApiName(a._1._2),
"basePath" -> a._1._1,
"operations" -> {
(for (t <- a._2) yield { Map("operation" -> t._2, "path" -> t._1) }).toList
})
})
apiList.toList
}
def modelListF(models: Map[String, Model]): List[Map[String, AnyRef]] = {
val modelList = new ListBuffer[HashMap[String, AnyRef]]
models.foreach(m => {
val json = write(m._2)
modelList += HashMap(
"modelName" -> m._1,
"model" -> m._2,
"filename" -> config.toModelFilename(m._1),
"modelJson" -> json,
"hasMore" -> "true")
})
modelList.size match {
case 0 =>
case _ => modelList.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
}
modelList.map(_.toMap).toList
}
def dataF(apis: Map[(String, String), List[(String, Operation)]],
models: Map[String, Model]): Map[String, AnyRef] =
Map(
"clientName" -> clientName.underscore.pascalize,
"projectName" -> clientName.underscore.dasherize,
"package" -> config.packageName,
"modelPackage" -> config.modelPackage,
"apiPackage" -> config.apiPackage,
"apis" -> apiListF(apis),
"models" -> modelListF(models))
writeSupportingClasses(apis, models, apiVersion, rootDir, dataF)
}
override def compileTemplate(templateFile: String, rootDir: Option[File] = None, engine: Option[TemplateEngine] = None): (String, (TemplateEngine, Template)) = {
val eng = engine getOrElse new TemplateEngine(rootDir orElse Some(new File(".")))
val rn = config.templateDir + File.separator + templateFile
val rrn = "asyncscala" + File.separator + templateFile
val resourceName = if (new File(rn).exists) rn else rrn
val is = getInputStream(resourceName)
if (is == null)
throw new Exception("Missing template: " + resourceName)
val template = eng.compile(TemplateSource.fromText(resourceName,Source.fromInputStream(is).mkString))
(resourceName, eng -> template)
}
*/
}
class ScalaAsyncClientGenerator(cfg: SwaggerGenConfig) extends BasicGenerator {
private[this] val pascalizedClientName = cfg.api.clientName.underscore.pascalize
override val packageName: String = cfg.api.packageName
override val templateDir: String = cfg.templateDir.getPath
override val destinationDir: String = cfg.codeDir.getPath
override val fileSuffix: String = ".scala"
override val modelPackage: Option[String] = Some(packageName + ".model")
override val apiPackage: Option[String] = Some(packageName + ".apis")
override val reservedWords: Set[String] =
Set(
"abstract",
"case",
"catch",
"class",
"def",
"do",
"else",
"extends",
"false",
"final",
"finally",
"for",
"forSome",
"if",
"implicit",
"import",
"lazy",
"match",
"new",
"null",
"object",
"override",
"package",
"private",
"protected",
"return",
"sealed",
"super",
"this",
"throw",
"trait",
"try",
"true",
"type",
"val",
"var",
"while",
"with",
"yield")
override val importMapping = Map(
"Date" -> "java.util.Date",
"File" -> "java.io.File"
) ++ cfg.defaultImports ++ cfg.api.defaultImports
override val typeMapping = Map(
"array" -> "List",
"boolean" -> "Boolean",
"string" -> "String",
"int" -> "Int",
"long" -> "Long",
"float" -> "Float",
"byte" -> "Byte",
"short" -> "Short",
"char" -> "Char",
"long" -> "Long",
"double" -> "Double",
"object" -> "Any",
"file" -> "File") ++ cfg.typeMapping
override val defaultIncludes = Set(
"Int",
"String",
"Long",
"Short",
"Char",
"Byte",
"Float",
"Double",
"Boolean",
"AnyRef",
"Any") ++ cfg.defaultIncludes ++ cfg.api.excludedModels
override def supportingFiles = List(
("client.mustache", destinationDir + "/" + cfg.api.packageName.replace('.', '/'), (pascalizedClientName +".scala")),
("sbt.mustache", cfg.projectRoot.getPath, "swagger-client.sbt")
)
modelTemplateFiles ++= cfg.api.modelTemplates
apiTemplateFiles ++= cfg.api.apiTemplates
codegen = new AsyncClientCodegen(cfg.api.clientName, this, Some(cfg.projectRoot))
override def getBasePath(host: String, basePath: String, fileMap: Option[String]): String =
cfg.api.baseUrl.getOrElse(super.getBasePath(host, basePath, fileMap))
/*
override def generateClient(args: Array[String]) = {
val host = cfg.api.resourceUrl
val authorization = {
val apiKey = cfg.api.apiKey
if(apiKey != None)
Some(ApiKeyValue("api_key", "query", apiKey.get))
else
None
}
val doc = {
try {
ResourceExtractor.fetchListing(getResourcePath(host, fileMap), authorization)
} catch {
case e: Exception => throw new Exception("unable to read from " + host, e)
}
}
implicit val basePath = getBasePath(host, doc.basePath, fileMap)
val apiReferences = doc.apis
if (apiReferences == null)
throw new Exception("No APIs specified by resource")
val apis = ApiExtractor.fetchApiListings(doc.swaggerVersion, basePath, apiReferences, authorization)
new SwaggerSpecValidator(doc, apis).validate()
val allModels = new mutable.HashMap[String, Model]
val operations = extractApiOperations(apis, allModels)
val operationMap = groupOperationsToFiles(operations)
val modelMap = prepareModelMap(allModels.toMap)
val modelFileContents = writeFiles(modelMap, modelTemplateFiles.toMap)
val modelFiles = new ListBuffer[File]()
for((filename, contents) <- modelFileContents) {
val file = new java.io.File(filename)
modelFiles += file
file.getParentFile().mkdirs
val fw = new FileWriter(filename, false)
fw.write(contents + "\n")
fw.close()
}
val apiBundle = prepareApiBundle(operationMap.toMap)
val apiInfo = writeFiles(apiBundle, apiTemplateFiles.toMap)
val apiFiles = new ListBuffer[File]()
apiInfo.map(m => {
val filename = m._1
val file = new java.io.File(filename)
apiFiles += file
file.getParentFile().mkdirs
val fw = new FileWriter(filename, false)
fw.write(m._2 + "\n")
fw.close()
println("wrote api " + filename)
})
codegen.writeSupportingClasses2(apiBundle, allModels.toMap, doc.apiVersion) ++
modelFiles ++ apiFiles
}
override def extractApiOperations(apiListings: List[ApiListing], allModels: mutable.HashMap[String, Model] )(implicit basePath:String) = {
val output = new mutable.ListBuffer[(String, String, Operation)]
apiListings.foreach(apiDescription => {
val basePath = apiDescription.basePath
val resourcePath = apiDescription.resourcePath
if(apiDescription.apis != null) {
apiDescription.apis.foreach(api => {
for ((apiPath, operation) <- ApiExtractor.extractApiOperations(basePath, api)) {
output += ((basePath, apiPath, operation))
}
})
}
output.map(op => processApiOperation(op._2, op._3))
allModels ++= CoreUtils.extractApiModels(apiDescription, defaultIncludes, typeMapping)
})
output.toList
}
override def toModelName(name: String) = toDeclaredType(name.pascalize)
*/
override def toApiName(name: String) = {
name.replaceAll("\\{","").replaceAll("\\}", "") match {
case s: String if(s.length > 0) => s.underscore.pascalize + "Client"
case _ => "Client"
}
}
//
// override def nameFromPath(apiPath: String) = resourceNameFromFullPath(apiPath)
//
//
// override def resourceNameFromFullPath(apiPath: String) =
// apiPath.split('/').head.split('.').head
/**
* creates a map of models and properties needed to write source
*/
/*
override def prepareModelMap(models: Map[String, Model]): List[Map[String, AnyRef]] = {
for {
(name, schema) <- (models -- defaultIncludes).toList
if !(cfg.excludedModelPackages ++ cfg.api.excludedModelPackages).exists(schema.qualifiedType.startsWith)
} yield {
Map(
"name" -> toModelName(name),
"className" -> name,
"filename" -> toModelFilename(name),
"apis" -> None,
"models" -> List((name, schema)),
"package" -> modelPackage,
"invokerPackage" -> invokerPackage,
"outputDirectory" -> (destinationDir + File.separator + modelPackage.getOrElse("").replaceAll("\\.", File.separator)),
"newline" -> "\n")
}
}
override def prepareApiBundle(apiMap: Map[(String, String), List[(String, Operation)]] ): List[Map[String, AnyRef]] = {
for {
((basePath, name), operationList) <- apiMap.toList
className = toApiName(name)
} yield {
Map(
"baseName" -> name,
"filename" -> toApiFilename(name),
"name" -> toApiName(name),
"className" -> className,
"basePath" -> basePath,
"package" -> apiPackage,
"invokerPackage" -> invokerPackage,
"apis" -> Map(className -> operationList.toList),
"models" -> None,
"outputDirectory" -> (destinationDir + File.separator + apiPackage.getOrElse("").replaceAll("\\.", File.separator)),
"newline" -> "\n")
}
}
def bundleToSource(bundle:List[Map[String, AnyRef]], templates: Map[String, String]): List[(String, String)] = {
bundle.foldLeft(List.empty[(String, String)]) { (acc, m) =>
templates.foldLeft(acc) { (out, tem) =>
val (file, suffix) = tem
(m("outputDirectory").toString + File.separator + m("filename").toString + suffix) -> codegen.generateSource(m, file) :: acc
}
}
}
def generateAndWrite(bundle: Map[String, AnyRef], templateFile: String) = {
val output = codegen.generateSource(bundle, templateFile)
val outputDir = new File(bundle("outputDirectory").asInstanceOf[String])
outputDir.mkdirs
val filename = outputDir + File.separator + bundle("filename")
val fw = new FileWriter(filename, false)
fw.write(output + "\n")
fw.close()
println("wrote " + filename)
}
*/
// response classes--if you don't want a response class, override and set to None
override def processResponseClass(responseClass: String): Option[String] = {
responseClass match {
case "void" => None //Some("Unit")
case e: String => Some(toDeclaredType(e))
}
}
override def processResponseDeclaration(responseClass: String): Option[String] = {
responseClass match {
case "void" => None //Some("Unit")
case e: String => Some(toDeclaredType(e))
}
}
override def toDeclaredType(dt: String): String = {
val declaredType = (dt.indexOf("[")) match {
case -1 => dt
case n: Int => {
if (dt.substring(0, n).toLowerCase == "array") {
val dtt = dt.substring(n + 1, dt.length - 1)
"List[%s]".format(typeMapping.getOrElse(dtt, dtt))
} else dt
}
}
typeMapping.getOrElse(declaredType, declaredType)
}
override def toDeclaration(obj: ModelProperty): (String, String) = {
obj.`type` match {
case "Array" | "array" => makeContainerType(obj, "List")
case "Set" | "set" => makeContainerType(obj, "Set")
case e: String => (toDeclaredType(e), toDefaultValue(e, obj))
}
}
private def makeContainerType(obj: ModelProperty, container: String): (String, String) = {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => throw new Exception("no inner type defined")
}
}
val e = "%s[%s]" format (container, toDeclaredType(inner))
(e, toDefaultValue(inner, obj))
}
// escape keywords
override def escapeReservedWord(word: String) = "`" + word + "`"
}

View File

@ -1,71 +0,0 @@
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.util.{ ResourceExtractor, ApiExtractor }
import com.wordnik.swagger.codegen.model._
import java.io.File
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{ read, write }
object SpecConverter {
def main(args: Array[String]) = {
implicit val formats = SwaggerSerializers.formats("1.2")
if(args == null || args.length < 2) {
println("Usage: SpecConverter {host} {outputDir}\nIf no API key is required, use an empty string")
sys.exit(0)
}
val url = args(0)
val key = None
val outputDir = new File(args(1))
if(!outputDir.exists) outputDir.mkdir
val resourcePath = url.split("/").last
val resourceListing = ResourceExtractor.fetchListing(url, key)
resourceListing.swaggerVersion match {
case "1.1" =>
case e: String => {
println("unsupported swagger version %s".format(e))
sys.exit(0)
}
}
val updatedListing = {
val apis = (for(api <- resourceListing.apis) yield {
val path = if(api.path.startsWith("/" + resourcePath)) {
api.path.substring(resourcePath.length + 1)
}
else api.path
api.copy(path = path.replace(".{format}",""))
}).toList
resourceListing.copy(apis = apis, swaggerVersion = "1.2")
}
writeToFile(outputDir + File.separator + "api-docs", write(updatedListing))
val listings = ApiExtractor.fetchApiListings(resourceListing.swaggerVersion, resourceListing.basePath, resourceListing.apis, key)
listings.foreach(listing => {
val apis = (for(api <- listing.apis) yield {
api.copy(path = api.path.replace(".{format}", ""))
})
val filename = listing.resourcePath.replace("/","")
val updatedApi = listing.copy(swaggerVersion = "1.2", apis = apis)
writeToFile(outputDir + File.separator + filename, write(updatedApi))
})
}
def writeToFile(p: String, s: String) {
val pw = new java.io.PrintWriter(new File(p))
try {
println("writing file %s".format(p))
pw.write(s)
} finally {
pw.close()
}
}
}

View File

@ -1,107 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen
import com.wordnik.swagger.codegen.spec.SwaggerSpec
import com.wordnik.swagger.codegen.model._
import scala.collection.mutable.{ HashMap, ListBuffer }
object SwaggerDocGenerator extends SwaggerDocGenerator {
def main(args: Array[String]) = generateClient(args)
}
class SwaggerDocGenerator extends BasicGenerator {
override def templateDir = "src/main/resources/swagger-static"
val outputFolder = "samples/swagger-static-docs"
// where to write generated code
override def destinationDir = outputFolder + "/docs"
// template used for apis
apiTemplateFiles += "operation.mustache" -> ".html"
modelTemplateFiles += "model.mustache" -> ".html"
override def toDeclaration(obj: ModelProperty): (String, String) = {
obj.`type` match {
case "Array" => {
val inner = {
obj.items match {
case Some(items) => items.ref.getOrElse(items.`type`)
case _ => {
println("failed on " + obj)
throw new Exception("no inner type defined")
}
}
}
val e = "List[%s]" format toDeclaredType(inner)
(e, toDefaultValue(inner, obj))
}
case e: String => (toDeclaredType(e), toDefaultValue(e, obj))
}
}
override def processApiMap(m: Map[String, AnyRef]): Map[String, AnyRef] = {
val mutable = scala.collection.mutable.Map() ++ m
mutable.map(k => {
k._1 match {
case "allParams" => {
val paramList = k._2.asInstanceOf[List[_]]
paramList.foreach(param => {
val map = param.asInstanceOf[scala.collection.mutable.HashMap[String, AnyRef]]
if(map.contains("dataType")){
val ComplexTypeMatcher = ".*\\[(.*)\\].*".r
val v = map("dataType") match {
case ComplexTypeMatcher(v) => v
case _ => map("dataType").asInstanceOf[String]
}
if(SwaggerSpec.primitives.contains(v)) {
map += "simpleType" -> v
}
else {
map += "complexType" -> v
}
}
})
}
case _ =>
}
})
mutable.toMap
}
// package for models
override def modelPackage: Option[String] = Some("models")
// package for api classes
override def apiPackage: Option[String] = Some("operations")
override def supportingFiles = List(
("package.mustache", outputFolder, "package.json"),
("main.mustache", outputFolder, "main.js"),
("assets/css/bootstrap-responsive.css", destinationDir + "/assets/css", "bootstrap-responsive.css"),
("assets/css/bootstrap.css", destinationDir + "/assets/css", "bootstrap.css"),
("assets/css/style.css", destinationDir + "/assets/css", "style.css"),
("assets/images/logo.png", destinationDir + "/assets/images", "logo.png"),
("assets/js/bootstrap.js", destinationDir + "/assets/js", "bootstrap.js"),
("assets/js/jquery-1.8.3.min.js", destinationDir + "/assets/js", "jquery-1.8.3.min.js"),
("assets/js/main.js", destinationDir + "/assets/js", "main.js"),
("index.mustache", destinationDir, "index.html")
)
}

View File

@ -1,156 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.language
import com.wordnik.swagger.codegen.model._
import scala.collection.mutable.{ HashMap, HashSet }
abstract class CodegenConfig {
/*
* abstract methods
*/
def packageName: String
def templateDir: String
def destinationDir: String
def toModelName(name: String): String
def toApiName(name: String): String
def toModelFilename(name: String) = name
def toApiFilename(name: String) = toApiName(name)
def apiNameFromPath(apiPath: String): String
def processApiMap(m: Map[String, AnyRef]): Map[String, AnyRef] = m
def processModelMap(m: Map[String, AnyRef]): Map[String, AnyRef] = m
val apiTemplateFiles = new HashMap[String, String]()
val modelTemplateFiles = new HashMap[String, String]()
val additionalParams = new HashMap[String, String]
def defaultIncludes = Set[String]()
def languageSpecificPrimitives = Set[String]()
def typeMapping = Map[String, String]()
// optional configs
def invokerPackage: Option[String] = None
def apiPackage: Option[String] = None
def modelPackage: Option[String] = None
def reservedWords: Set[String] = Set()
// swagger primitive types
def importMapping: Map[String, String] = Map()
def escapeReservedWord(word: String) = word
// only process these apis (by name)
val apisToProcess = new HashSet[String]
// only process these models
val modelsToProcess = new HashSet[String]
// method name from operation.nickname
def toMethodName(name: String): String = name
// override if you want to do something special on processing
// def processOperation(apiPath: String, op: DocumentationOperation) = {}
def processOperation(apiPath: String, op: Operation) = {}
def processResponseClass(responseClass: String): Option[String] = Some(responseClass)
def processApiOperation(apiPath: String, op: Operation) = {}
def processResponseDeclaration(responseClass: String): Option[String] = {
responseClass match {
case "void" => None
case e: String => Some(toDeclaredType(e))
}
}
def supportingFiles = List(): List[(String, String, String)]
// mapping for datatypes
def toDeclaration(property: ModelProperty) = {
var declaredType = toDeclaredType(property.`type`)
val defaultValue = toDefaultValue(declaredType, property)
(declaredType, defaultValue)
}
def toDeclaredType(dataType: String): String = {
typeMapping.getOrElse(dataType, dataType)
}
def toGetter(name: String, datatype: String) = {
val base = datatype match {
case "boolean" => "is"
case _ => "get"
}
base + {
if (name.length > 0) name(0).toUpper + name.substring(1)
else ""
}
}
def toSetter(name: String, datatype: String) = {
val base = datatype match {
case _ => "set"
}
base + {
if (name.length > 0) name(0).toUpper + name.substring(1)
else ""
}
}
def toVarName(name: String): String = {
name match {
case _ if (reservedWords.contains(name)) => escapeReservedWord(name)
case _ => name
}
}
def toDefaultValue(datatype: String, v: String): Option[String] = {
if (v != "" && v != null) {
datatype match {
case "int" => Some(v)
case "long" => Some(v)
case "double" => Some(v)
case x if x == "string" || x == "String" => {
v match {
case e: String => Some("\"" + v + "\"")
case _ => None
}
}
case _ => None
}
} else None
}
def toDefaultValue(dataType: String, obj: ModelProperty) = {
dataType match {
case "int" => "0"
case "long" => "0L"
case "float" => "0f"
case "double" => "0.0"
case e: String if (Set("List").contains(e)) => {
val inner =
obj.items.map(i => i.ref.getOrElse(i.`type`)).getOrElse({
println("failed on " + dataType + ", " + obj)
throw new Exception("no inner type defined")
})
"List.empty[" + toDeclaredType(inner) + "]"
}
case _ => "_"
}
}
}

View File

@ -1,46 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.model
trait AuthorizationType {
def `type`: String
}
case class OAuth(
scopes: List[String],
grantTypes: List[GrantType]) extends AuthorizationType {
override def `type` = "oauth2"
}
case class ApiKey(keyname: String, passAs: String = "header") extends AuthorizationType {
override def `type` = "apiKey"
}
trait GrantType {
def `type`: String
}
case class ImplicitGrant(
loginEndpoint: LoginEndpoint,
tokenName: String) extends GrantType {
def `type` = "implicit"
}
case class AuthorizationCodeGrant(
tokenRequestEndpoint: TokenRequestEndpoint,
tokenEndpoint: TokenEndpoint) extends GrantType {
def `type` = "authorization_code"
}
trait AuthorizationValue
case class ApiKeyValue(keyName: String, passAs: String, value: String) extends AuthorizationValue

View File

@ -1,23 +0,0 @@
package com.wordnik.swagger.codegen.model
import scala.beans.BeanProperty
import scala.collection.JavaConverters._
class ClientOpts(
@BeanProperty var uri: String,
@BeanProperty var auth: Option[ApiKeyValue],
@BeanProperty var properties: java.util.Map[String, String]) {
def this() = this(null, None, new java.util.HashMap[String, String]())
@BeanProperty var outputDirectory: String = _
override def toString() = {
val sb = new StringBuilder()
sb.append("ClientOpts: {\n")
sb.append(" uri: ").append(uri).append(",")
sb.append(" auth: ").append(auth).append(",")
sb.append(properties.asScala.mkString(" ", ",", "\n"))
sb.append("}")
sb.toString
}
}

View File

@ -1,351 +0,0 @@
package com.wordnik.swagger.codegen.model.legacy
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.spec.ValidationMessage
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{read, write}
import scala.collection.mutable.{ListBuffer, LinkedHashMap}
object LegacySerializers {
import ValidationMessage._
val formats = DefaultFormats +
new ModelSerializer +
new ModelPropertySerializer +
new ModelRefSerializer +
new AllowableValuesSerializer +
new ParameterSerializer +
new OperationSerializer +
new ResponseMessageSerializer +
new ApiDescriptionSerializer +
new ApiListingReferenceSerializer +
new ResourceListingSerializer +
new ApiListingSerializer
class ApiListingSerializer extends CustomSerializer[ApiListing](formats => ({
case json =>
implicit val fmts: Formats = formats
ApiListing(
(json \ "apiVersion").extractOrElse(""),
(json \ "swaggerVersion").extractOrElse(""),
(json \ "basePath").extractOrElse(""),
(json \ "resourcePath").extractOrElse(""),
List.empty,
List.empty,
List.empty,
List.empty,
(json \ "apis").extract[List[ApiDescription]],
(json \ "models").extractOpt[Map[String, Model]],
(json \ "description").extractOpt[String],
0
)
}, {
case x: ApiListing =>
implicit val fmts = formats
("apiVersion" -> x.apiVersion) ~
("swaggerVersion" -> x.swaggerVersion) ~
("basePath" -> x.basePath) ~
("apis" -> {
x.apis match {
case e: List[ApiDescription] if (e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
}) ~
("models" -> {
x.models match {
case e: Map[String, Model] if (e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
})
}
))
class ResourceListingSerializer extends CustomSerializer[ResourceListing](formats => ({
case json =>
implicit val fmts: Formats = formats
ResourceListing(
(json \ "apiVersion").extractOrElse(""),
(json \ "swaggerVersion").extractOrElse(""),
(json \ "basePath").extractOrElse(""),
(json \ "apis").extract[List[ApiListingReference]]
)
}, {
case x: ResourceListing =>
implicit val fmts = formats
("apiVersion" -> x.apiVersion) ~
("swaggerVersion" -> x.swaggerVersion) ~
("basePath" -> x.basePath) ~
("apis" -> {
x.apis match {
case e: List[ApiListingReference] if (e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
})
}
))
class ApiListingReferenceSerializer extends CustomSerializer[ApiListingReference](formats => ({
case json =>
implicit val fmts: Formats = formats
ApiListingReference(
(json \ "path").extractOrElse(""),
(json \ "description").extractOpt[String]
)
}, {
case x: ApiListingReference =>
implicit val fmts = formats
("path" -> x.path) ~
("description" -> x.description)
}
))
class ApiDescriptionSerializer extends CustomSerializer[ApiDescription](formats => ({
case json =>
implicit val fmts: Formats = formats
ApiDescription(
(json \ "path").extractOrElse(""),
(json \ "description").extractOpt[String],
(json \ "operations").extract[List[Operation]]
)
}, {
case x: ApiDescription =>
implicit val fmts = formats
("path" -> x.path) ~
("description" -> x.description) ~
("operations" -> {
x.operations match {
case e:List[Operation] if(e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
})
}
))
class ResponseMessageSerializer extends CustomSerializer[ResponseMessage](formats => ({
case json =>
implicit val fmts: Formats = formats
ResponseMessage(
(json \ "code").extractOrElse(0),
(json \ "reason").extractOrElse("")
)
}, {
case x: ResponseMessage =>
implicit val fmts = formats
("code" -> x.code) ~
("message" -> x.message)
}
))
class OperationSerializer extends CustomSerializer[Operation](formats => ({
case json =>
implicit val fmts: Formats = formats
val authorizations = (json \ "authorizations").extractOpt[Map[String, AuthorizationType]] match {
case Some(m) => m.values.toList
case _ => List.empty
}
Operation(
(json \ "httpMethod").extractOrElse(
(json \ "method").extractOrElse("")
),
(json \ "summary").extract[String],
(json \ "notes").extractOrElse(""),
(json \ "responseClass").extractOrElse(""),
(json \ "nickname").extractOrElse(""),
(json \ "position").extractOrElse(0),
(json \ "produces").extract[List[String]],
(json \ "consumes").extract[List[String]],
(json \ "protocols").extract[List[String]],
authorizations,
(json \ "parameters").extract[List[Parameter]],
(json \ "errorResponses").extract[List[ResponseMessage]],
(json \ "deprecated").extractOpt[String]
)
}, {
case x: Operation =>
implicit val fmts = formats
("method" -> x.method) ~
("summary" -> x.summary) ~
("notes" -> x.notes) ~
("responseClass" -> x.responseClass) ~
("nickname" -> x.nickname) ~
("parameters" -> Extraction.decompose(x.parameters)) ~
("responseMessages" -> {
x.responseMessages match {
case e: List[ResponseMessage] if(e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
}) ~
("deprecated" -> x.`deprecated`)
}
))
class ParameterSerializer extends CustomSerializer[Parameter](formats => ({
case json =>
implicit val fmts: Formats = formats
Parameter(
(json \ "name").extractOrElse(""),
(json \ "description").extractOpt[String],
(json \ "defaultValue") match {
case e:JInt => Some(e.num.toString)
case e:JBool => Some(e.value.toString)
case e:JString => Some(e.s)
case e:JDouble => Some(e.num.toString)
case _ => None
},
(json \ "required") match {
case e:JString => e.s.toBoolean
case e:JBool => e.value
case _ => false
},
(json \ "allowMultiple").extractOrElse(false),
(json \ "dataType").extractOrElse(""),
(json \ "allowableValues").extract[AllowableValues],
(json \ "paramType").extractOrElse("")
)
}, {
case x: Parameter =>
implicit val fmts = formats
("name" -> x.name) ~
("description" -> x.description) ~
("defaultValue" -> x.defaultValue) ~
("required" -> x.required) ~
("allowMultiple" -> x.allowMultiple) ~
("dataType" -> x.dataType) ~
("allowableValues" -> {
x.allowableValues match {
case AnyAllowableValues => JNothing // don't serialize when not a concrete type
case e:AllowableValues => Extraction.decompose(x.allowableValues)
case _ => JNothing
}
}) ~
("paramType" -> x.paramType)
}
))
class ModelSerializer extends CustomSerializer[Model](formats => ({
case json =>
implicit val fmts: Formats = formats
val output = new LinkedHashMap[String, ModelProperty]
val properties = (json \ "properties") match {
case JObject(entries) => {
entries.map({
case (key, value) => output += key -> value.extract[ModelProperty]
})
}
case _ =>
}
Model(
(json \ "id").extractOrElse(""),
(json \ "name").extractOrElse(""),
(json \ "id").extractOrElse(""),
output,
(json \ "description").extractOpt[String]
)
}, {
case x: Model =>
implicit val fmts = formats
("id" -> x.id) ~
("name" -> x.name) ~
("properties" -> {
x.properties match {
case e: LinkedHashMap[String, ModelProperty] => Extraction.decompose(e.toMap)
case _ => JNothing
}
})
}
))
class ModelPropertySerializer extends CustomSerializer[ModelProperty] (formats => ({
case json =>
implicit val fmts: Formats = formats
ModelProperty(
`type` = (json \ "type").extractOrElse(""),
`qualifiedType` = (json \ "type").extractOrElse(""),
required = (json \ "required") match {
case e:JString => e.s.toBoolean
case e:JBool => e.value
case _ => false
},
description = (json \ "description").extractOpt[String],
allowableValues = (json \ "allowableValues").extract[AllowableValues],
items = {
(json \ "items").extractOpt[ModelRef] match {
case Some(e: ModelRef) if(e.`type` != null || e.ref != None) => Some(e)
case _ => None
}
}
)
}, {
case x: ModelProperty =>
implicit val fmts = formats
("type" -> x.`type`) ~
("required" -> x.required) ~
("description" -> x.description) ~
("allowableValues" -> {
x.allowableValues match {
case AnyAllowableValues => JNothing // don't serialize when not a concrete type
case e:AllowableValues => Extraction.decompose(x.allowableValues)
case _ => JNothing
}
}) ~
("items" -> Extraction.decompose(x.items))
}
))
class ModelRefSerializer extends CustomSerializer[ModelRef](formats => ({
case json =>
implicit val fmts: Formats = formats
ModelRef(
(json \ "type").extractOrElse(null: String),
(json \ "$ref").extractOpt[String]
)
}, {
case x: ModelRef =>
implicit val fmts = formats
("type" -> {
x.`type` match {
case e:String => Some(e)
case _ => None
}
}) ~
("$ref" -> x.ref)
}
))
class AllowableValuesSerializer extends CustomSerializer[AllowableValues](formats => ({
case json =>
implicit val fmts: Formats = formats
json \ "valueType" match {
case JString(x) if x.equalsIgnoreCase("list") => {
val output = new ListBuffer[String]
val properties = (json \ "values") match {
case JArray(entries) => entries.map {
case e:JInt => output += e.num.toString
case e:JBool => output += e.value.toString
case e:JString => output += e.s
case e:JDouble => output += e.num.toString
case _ =>
}
case _ =>
}
AllowableListValues(output.toList)
}
case JString(x) if x.equalsIgnoreCase("range") =>
AllowableRangeValues((json \ "min").extract[String], (json \ "max").extract[String])
case _ => AnyAllowableValues
}
}, {
case AllowableListValues(values, "LIST") =>
implicit val fmts = formats
("valueType" -> "LIST") ~ ("values" -> Extraction.decompose(values))
case AllowableRangeValues(min, max) =>
("valueType" -> "RANGE") ~ ("min" -> min) ~ ("max" -> max)
}
))
}

View File

@ -1,634 +0,0 @@
package com.wordnik.swagger.codegen.model
import com.wordnik.swagger.codegen.spec.ValidationMessage
import com.wordnik.swagger.util.ValidationException
import legacy.LegacySerializers
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{read, write}
import scala.collection.mutable.{ListBuffer, LinkedHashMap}
object SwaggerSerializers {
import ValidationMessage._
val jsonSchemaTypeMap = Map(
// simple types
("integer", "int32") -> "int",
("integer", "int64") -> "long",
("number", "float") -> "float",
("number", "double") -> "double",
("number", null) -> "BigDecimal",
("string", "byte") -> "byte",
("string", "date") -> "Date",
("string", "date-time") -> "Date",
("string", "uuid") -> "UUID",
// containers
("array", "") -> "Array",
("set", "") -> "Set"
)
def toJsonSchema(name: String, `type`: String): JObject = {
`type` match {
case "int" => (name -> "integer") ~ ("format" -> "int32")
case "long" => (name -> "integer") ~ ("format" -> "int64")
case "float" => (name -> "number") ~ ("format" -> "float")
case "double" => (name -> "number") ~ ("format" -> "double")
case "string" => (name -> "string") ~ ("format" -> JNothing)
case "byte" => (name -> "string") ~ ("format" -> "byte")
case "boolean" => (name -> "boolean") ~ ("format" -> JNothing)
case "Date" => (name -> "string") ~ ("format" -> "date-time")
case "date" => (name -> "string") ~ ("format" -> "date")
case "date-time" => (name -> "string") ~ ("format" -> "date-time")
case "Array" => (name -> "array")
case _ => {
val ComplexTypeMatcher = "([a-zA-Z]*)\\[([a-zA-Z\\.\\-]*)\\].*".r
`type` match {
case ComplexTypeMatcher(container, value) =>
toJsonSchemaContainer(container) ~ {
("items" -> {if(isSimpleType(value))
toJsonSchema("type", value)
else
toJsonSchema("$ref", value)})
}
case _ => (name -> `type`) ~ ("format" -> JNothing)
}
}
}
}
def toJsonSchemaContainer(name: String): JObject = {
name match {
case "List" => ("type" -> "array") ~ ("format" -> JNothing)
case "Array" => ("type" -> "array") ~ ("format" -> JNothing)
case "Set" => ("type" -> "array") ~ ("uniqueItems" -> true)
case _ => ("type" -> JNothing)
}
}
def isSimpleType(name: String) = {
Set("int", "long", "float", "double", "string", "byte", "boolean", "Date", "date", "date-time", "array", "set").contains(name)
}
def formats(version: String) = {
version match {
case "1.1" => LegacySerializers.formats
case "1.2" => {
DefaultFormats +
new ModelSerializer +
new ModelPropertySerializer +
new ModelRefSerializer +
new AllowableValuesSerializer +
new ParameterSerializer +
new OperationSerializer +
new ResponseMessageSerializer +
new ApiDescriptionSerializer +
new ApiListingReferenceSerializer +
new ResourceListingSerializer +
new ApiListingSerializer
}
case _ => {
val error = ValidationError("ResourceListing", "swaggerVersion", SwaggerValidator.ERROR)
throw new ValidationException(400, "'%s' is not a valid Swagger version".format(version), List(error))
}
}
}
class ApiListingSerializer extends CustomSerializer[ApiListing](implicit formats => ({
case json =>
val authorizations = (json \ "authorizations").extractOpt[Map[String, AuthorizationType]] match {
case Some(m) => m.values.toList
case _ => List.empty
}
val swaggerVersion = (json \ "swaggerVersion") match {
case e: JInt => e.num.toString
case e: JBool => e.value.toString
case e: JString => e.s
case e: JDouble => e.num.toString
case _ => ""
}
ApiListing(
(json \ "apiVersion").extractOrElse(""),
swaggerVersion,
(json \ "basePath").extractOrElse(""),
(json \ "resourcePath").extractOrElse(""),
(json \ "produces").extract[List[String]],
(json \ "consumes").extract[List[String]],
(json \ "protocols").extract[List[String]],
authorizations,
(json \ "apis").extract[List[ApiDescription]],
(json \ "models").extractOpt[Map[String, Model]],
(json \ "description").extractOpt[String],
(json \ "position").extractOrElse(0)
)
}, {
case x: ApiListing =>
("apiVersion" -> x.apiVersion) ~
("resourcePath" -> x.resourcePath) ~
("swaggerVersion" -> x.swaggerVersion) ~
("basePath" -> x.basePath) ~
("apis" -> {
x.apis match {
case e: List[ApiDescription] if (e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
}) ~
("models" -> {
x.models match {
case Some(e) if (e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
})
}
))
class ResourceListingSerializer extends CustomSerializer[ResourceListing](implicit formats => ({
case json =>
val apis = (json \ "apis").extract[List[ApiListingReference]]
val swaggerVersion = (json \ "swaggerVersion") match {
case e: JInt => e.num.toString
case e: JBool => e.value.toString
case e: JString => e.s
case e: JDouble => e.num.toString
case _ => ""
}
ResourceListing(
(json \ "apiVersion").extractOrElse(""),
swaggerVersion,
"",
apis.filter(a => a.path != "" && a.path != null)
)
}, {
case x: ResourceListing =>
("apiVersion" -> x.apiVersion) ~
("swaggerVersion" -> x.swaggerVersion) ~
("apis" -> {
x.apis match {
case e: List[ApiListingReference] if (e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
})
}
))
class ApiListingReferenceSerializer extends CustomSerializer[ApiListingReference](implicit formats => ({
case json =>
val path = (json \ "path").extractOrElse({
(json \ "resourcePath").extractOrElse("")
})
ApiListingReference(
path,
(json \ "description").extractOpt[String]
)
}, {
case x: ApiListingReference =>
("path" -> x.path) ~
("description" -> x.description)
}
))
class ApiDescriptionSerializer extends CustomSerializer[ApiDescription](implicit formats => ({
case json =>
ApiDescription(
(json \ "path").extractOrElse(""),
(json \ "description").extractOpt[String],
(json \ "operations").extract[List[Operation]]
)
}, {
case x: ApiDescription =>
("path" -> x.path) ~
("description" -> x.description) ~
("operations" -> {
x.operations match {
case e:List[Operation] if(e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
})
}
))
class ResponseMessageSerializer extends CustomSerializer[ResponseMessage](implicit formats => ({
case json =>
val responseClass = (json \ "responseModel") match {
case e: JObject => {
val inner = {
(e \ "items" \"type").extractOrElse({
(e \ "items" \ "$ref").extract[String]
})
}
Option("%s[%s]".format((e \ "type").extract[String], inner))
}
case _ => (json \ "responseModel").extractOpt[String]
}
ResponseMessage(
(json \ "code").extractOrElse(0),
(json \ "message").extractOrElse(""),
(json \ "responseModel").extractOpt[String]
)
}, {
case x: ResponseMessage =>
("code" -> x.code) ~
("message" -> x.message) ~
("responseModel" -> x.responseModel)
}
))
class OperationSerializer extends CustomSerializer[Operation](implicit formats => ({
case json =>
val authorizations = (json \ "authorizations").extractOpt[Map[String, AuthorizationType]] match {
case Some(m) => m.values.toList
case _ => List.empty
}
val t = SwaggerSerializers.jsonSchemaTypeMap.getOrElse(
((json \ "type").extractOrElse(""), (json \ "format").extractOrElse(""))
, (json \ "type").extractOrElse(""))
val inner = {
val items = new scala.collection.mutable.HashSet[String]
val map = new scala.collection.mutable.HashMap[String, String]
(json \ "items") match {
case JObject(e) => {
for(a <- e) {
a._2 match {
case e: JString => map += a._1 -> e.s
case _ =>
}
}
val `type` = map.getOrElse("type", "")
val format = map.getOrElse("format", "")
if(map.contains("$ref")) {
Some(map("$ref"))
}
else
Option(jsonSchemaTypeMap.getOrElse((`type`,format), `type`))
}
case _ => None
}
}
val responseClass = inner match {
case Some(a) => "%s[%s]".format(t, a)
case _ => t
}
Operation(
(json \ "httpMethod").extractOrElse(
(json \ "method").extractOrElse("")
),
(json \ "summary").extract[String],
(json \ "notes").extractOrElse(""),
responseClass,
(json \ "nickname").extractOrElse(""),
(json \ "position").extractOrElse(0),
(json \ "produces").extract[List[String]],
(json \ "consumes").extract[List[String]],
(json \ "protocols").extract[List[String]],
authorizations,
(json \ "parameters").extract[List[Parameter]],
(json \ "responseMessages").extract[List[ResponseMessage]],
(json \ "deprecated").extractOpt[String]
)
}, {
case x: Operation =>
val ComplexTypeMatcher = "([a-zA-Z]*)\\[([a-zA-Z\\.\\-]*)\\].*".r
val output = x.responseClass match {
case ComplexTypeMatcher(container, value) =>
toJsonSchemaContainer(container) ~ {
("items" -> {if(isSimpleType(value))
toJsonSchema("type", value)
else
toJsonSchema("$ref", value)})
}
case _ => toJsonSchema("type", x.responseClass) ~ ("format" -> JNothing)
}
("method" -> x.method) ~
("summary" -> x.summary) ~
("notes" -> x.notes) ~
output ~
("nickname" -> x.nickname) ~
("parameters" -> Extraction.decompose(x.parameters)) ~
("responseMessages" -> {
x.responseMessages match {
case e: List[ResponseMessage] if(e.size > 0) => Extraction.decompose(e)
case _ => JNothing
}
}) ~
("deprecated" -> x.`deprecated`)
}
))
class ParameterSerializer extends CustomSerializer[Parameter](formats => ({
case json =>
implicit val fmts: Formats = formats
val output = new ListBuffer[String]
(json \ "enum") match {
case JArray(entries) => entries.map {
case e: JInt => output += e.num.toString
case e: JBool => output += e.value.toString
case e: JString => output += e.s
case e: JDouble => output += e.num.toString
case _ =>
}
case _ =>
}
val allowableValues = {
if(output.size > 0) AllowableListValues(output.toList)
else {
val min = (json \ "min") match {
case e: JObject => e.extract[String]
case e: JString => e.s
case e: JInt => e.num.toString
case e: JDouble => e.num.toString
case _ => ""
}
val max = (json \ "max") match {
case e: JObject => e.extract[String]
case e: JString => e.s
case e: JInt => e.num.toString
case e: JDouble => e.num.toString
case _ => ""
}
if(min != "" && max != "")
AllowableRangeValues(min, max)
else
AnyAllowableValues
}
}
val t = SwaggerSerializers.jsonSchemaTypeMap.getOrElse(
((json \ "type").extractOrElse(""), (json \ "format").extractOrElse(""))
, (json \ "type").extractOrElse(""))
val inner = {
val items = new scala.collection.mutable.HashSet[String]
val map = new scala.collection.mutable.HashMap[String, String]
(json \ "items") match {
case JObject(e) => {
for(a <- e) {
a._2 match {
case e: JString => map += a._1 -> e.s
case _ =>
}
}
val `type` = map.getOrElse("type", "")
val format = map.getOrElse("format", "")
if(map.contains("$ref")) {
Some(map("$ref"))
}
else
Option(jsonSchemaTypeMap.getOrElse((`type`,format), `type`))
}
case _ => None
}
}
val `type` = inner match {
case Some(a) => "%s[%s]".format(t, a)
case _ => t
}
Parameter(
name = (json \ "name").extractOrElse(""),
description = (json \ "description").extractOpt[String],
defaultValue = (json \ "defaultValue") match {
case e:JInt => Some(e.num.toString)
case e:JBool => Some(e.value.toString)
case e:JString => Some(e.s)
case e:JDouble => Some(e.num.toString)
case _ => None
},
required = (json \ "required") match {
case e:JString => e.s.toBoolean
case e:JBool => e.value
case _ => false
},
allowMultiple = (json \ "allowMultiple").extractOrElse(false),
dataType = `type`,
allowableValues = allowableValues,
paramType = (json \ "paramType").extractOrElse("")
)
}, {
case x: Parameter =>
implicit val fmts = formats
val output = ("name" -> x.name) ~
("description" -> x.description) ~
("defaultValue" -> x.defaultValue) ~
("required" -> x.required) ~
("allowMultiple" -> x.allowMultiple) ~
toJsonSchema("type", x.dataType) ~
("paramType" -> x.paramType)
x.allowableValues match {
case AllowableListValues(values, "LIST") =>
output ~ ("enum" -> Extraction.decompose(values))
case AllowableRangeValues(min, max) =>
output ~ ("minimum" -> min) ~ ("maximum" -> max)
case _ => output
}
}
))
class ModelSerializer extends CustomSerializer[Model](implicit formats => ({
case json =>
val output = new LinkedHashMap[String, ModelProperty]
val required = (json \ "required").extract[Set[String]]
json \ "properties" match {
case JObject(entries) => {
entries.map({
case (key, value) => {
val prop = value.extract[ModelProperty]
if(required.contains(key))
output += key -> prop.copy(required = true)
else
output += key -> prop
}
})
}
case _ =>
}
Model(
(json \ "id").extractOrElse(""),
(json \ "name").extractOrElse(""),
(json \ "qualifiedType").extractOrElse((json \ "id").extractOrElse("")),
output,
(json \ "description").extractOpt[String]
)
}, {
case x: Model =>
val required: List[String] = (for((name, prop) <- x.properties) yield {
if(prop.required) Some(name)
else None
}).flatten.toList
("id" -> x.id) ~
("name" -> x.name) ~
("required" -> (required.size match {
case 0 => JNothing
case _ => Extraction.decompose(required)
})) ~
("properties" -> {
(x.properties: @unchecked) match {
case e: LinkedHashMap[String, ModelProperty] => Extraction.decompose(e.toMap)
case _ => JNothing
}
})
}
))
class ModelPropertySerializer extends CustomSerializer[ModelProperty] (implicit formats => ({
case json =>
val `type` = (json \ "$ref") match {
case e: JString => e.s
case _ => {
// convert the jsonschema types into swagger types. Note, this logic will move elsewhere soon
val t = SwaggerSerializers.jsonSchemaTypeMap.getOrElse(
((json \ "type").extractOrElse(""), (json \ "format").extractOrElse(""))
, (json \ "type").extractOrElse(""))
val isUnique = (json \ "uniqueItems") match {
case e: JBool => e.value
case e: JString => e.s.toBoolean
case _ => false
}
if(t == "Array" && isUnique) "Set"
else t
}
}
val output = new ListBuffer[String]
json \ "enum" match {
case JArray(entries) => entries.map {
case e: JInt => output += e.num.toString
case e: JBool => output += e.value.toString
case e: JString => output += e.s
case e: JDouble => output += e.num.toString
case _ =>
}
case _ =>
}
val allowableValues = {
if(output.size > 0) AllowableListValues(output.toList)
else {
val min = (json \ "min") match {
case e: JObject => e.extract[String]
case _ => ""
}
val max = (json \ "max") match {
case e: JObject => e.extract[String]
case _ => ""
}
if(min != "" && max != "")
AllowableRangeValues(min, max)
else
AnyAllowableValues
}
}
ModelProperty(
`type` = `type`,
`qualifiedType` = (json \ "qualifiedType").extractOpt[String].getOrElse(`type`),
required = (json \ "required") match {
case e:JString => e.s.toBoolean
case e:JBool => e.value
case _ => false
},
description = (json \ "description").extractOpt[String],
allowableValues = allowableValues,
items = {
(json \ "items").extractOpt[ModelRef] match {
case Some(e: ModelRef) if(e.`type` != null || e.ref != None) => Some(e)
case _ => None
}
}
)
}, {
case x: ModelProperty =>
val output = toJsonSchema("type", x.`type`) ~
("description" -> x.description) ~
("items" -> Extraction.decompose(x.items))
x.allowableValues match {
case AllowableListValues(values, "LIST") =>
output ~ ("enum" -> Extraction.decompose(values))
case AllowableRangeValues(min, max) =>
output ~ ("minimum" -> min) ~ ("maximum" -> max)
case _ => output
}
}
))
class ModelRefSerializer extends CustomSerializer[ModelRef](implicit formats => ({
case json =>
val `type` = (json \ "type") match {
case e: JString => e.s
case _ => ""
}
val format = (json \ "format") match {
case e: JString => e.s
case _ => ""
}
val jsonSchemaType = jsonSchemaTypeMap.getOrElse((`type`, format), `type`)
ModelRef(
jsonSchemaType match {
case e: String if(e != "") => e
case _ => null
},
(json \ "$ref").extractOpt[String]
)
}, {
case x: ModelRef =>
("type" -> {
x.`type` match {
case e:String => Some(e)
case _ => None
}
}) ~
("$ref" -> x.ref)
}
))
class AllowableValuesSerializer extends CustomSerializer[AllowableValues](implicit formats => ({
case json =>
json \ "valueType" match {
case JString(x) if x.equalsIgnoreCase("list") => {
val output = new ListBuffer[String]
val properties = (json \ "values") match {
case JArray(entries) => entries.map {
case e:JInt => output += e.num.toString
case e:JBool => output += e.value.toString
case e:JString => output += e.s
case e:JDouble => output += e.num.toString
case _ =>
}
case _ =>
}
AllowableListValues(output.toList)
}
case JString(x) if x.equalsIgnoreCase("range") =>
AllowableRangeValues((json \ "min").extract[String], (json \ "max").extract[String])
case _ => AnyAllowableValues
}
}, {
case AllowableListValues(values, "LIST") =>
("valueType" -> "LIST") ~ ("values" -> Extraction.decompose(values))
case AllowableRangeValues(min, max) =>
("valueType" -> "RANGE") ~ ("min" -> min) ~ ("max" -> max)
}
))
}

View File

@ -1,119 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.model
import scala.collection.mutable.LinkedHashMap
case class ResourceListing(
apiVersion: String,
swaggerVersion: String,
basePath: String,
apis: List[ApiListingReference] = List(),
authorizations: List[AuthorizationType] = List(),
info: Option[ApiInfo] = None)
case class ApiInfo(
title: String,
description: String,
termsOfServiceUrl: String,
contact: String,
license: String,
licenseUrl: String)
case class LoginEndpoint(url: String)
case class TokenRequestEndpoint(url: String, clientIdName: String, clientSecretName: String)
case class TokenEndpoint(url: String, tokenName: String)
case class ApiListingReference(path:String, description: Option[String], position: Int = 0)
trait AllowableValues
case object AnyAllowableValues extends AllowableValues
case class AllowableListValues (values: List[String] = List(), valueType: String = "LIST") extends AllowableValues
case class AllowableRangeValues(min: String, max: String) extends AllowableValues
case class Model(
var id: String,
var name: String,
qualifiedType: String,
var properties: LinkedHashMap[String, ModelProperty],
description: Option[String] = None,
baseModel: Option[String] = None,
discriminator: Option[String] = None)
case class ModelProperty(
var `type`: String,
qualifiedType: String,
position: Int = 0,
required: Boolean = false,
description: Option[String] = None,
allowableValues: AllowableValues = AnyAllowableValues,
var items: Option[ModelRef] = None)
case class ModelRef(
`type`: String,
ref: Option[String] = None,
qualifiedType: Option[String] = None)
case class ApiListing (
apiVersion: String,
swaggerVersion: String,
basePath: String,
var resourcePath: String,
var produces: List[String] = List.empty,
var consumes: List[String] = List.empty,
var protocols: List[String] = List.empty,
var authorizations: List[AuthorizationType] = List.empty,
apis: List[ApiDescription] = List(),
models: Option[Map[String, Model]] = None,
description: Option[String] = None,
position: Int = 0)
case class ApiDescription (
path: String,
description: Option[String],
operations: List[Operation] = List())
case class Operation (
method: String,
summary: String,
notes: String,
var responseClass: String,
nickname: String,
position: Int,
var produces: List[String] = List.empty,
var consumes: List[String] = List.empty,
var protocols: List[String] = List.empty,
var authorizations: List[AuthorizationType] = List.empty,
parameters: List[Parameter] = List.empty,
responseMessages: List[ResponseMessage] = List.empty,
`deprecated`: Option[String] = None)
case class Parameter (
name: String,
description: Option[String],
defaultValue: Option[String],
required: Boolean,
allowMultiple: Boolean,
var dataType: String,
allowableValues: AllowableValues = AnyAllowableValues,
paramType: String,
paramAccess: Option[String] = None)
case class ResponseMessage (
code: Int,
message: String,
responseModel: Option[String] = None)

View File

@ -1,103 +0,0 @@
package com.wordnik.swagger.codegen.model
import scala.collection.mutable.ListBuffer
case class ValidationError (
path: String,
message: String,
severity: String
)
object SwaggerValidator {
val ERROR = "ERROR"
val WARNING = "WARNING"
def validate (resource: ResourceListing): List[ValidationError] = {
val errors = new ListBuffer[ValidationError]
if(resource.apiVersion == "")
errors += ValidationError("resourceListing", "apiVersion is required", ERROR)
if(resource.swaggerVersion == "")
errors += ValidationError("resourceListing", "apiVersion is required", ERROR)
for(api <- resource.apis)
validate(api, errors, "resourceListing")
errors.toList
}
def validate(ref: ApiListingReference, errors: ListBuffer[ValidationError], parent: String): Unit = {
if(ref.path == "")
errors += ValidationError(parent + ":[api]", "path is required", ERROR)
}
def validate(api: ApiListing, errors: ListBuffer[ValidationError]): Unit = {
if(api.swaggerVersion == "")
errors += ValidationError("apiDeclaration", "swaggerVersion is required", ERROR)
if(api.apiVersion == "")
errors += ValidationError("apiDeclaration", "apiVersion is required", ERROR)
if(api.basePath == "")
errors += ValidationError("apiDeclaration", "basePath is required", ERROR)
if(api.resourcePath == "")
errors += ValidationError("apiDeclaration", "resourcePath is required", ERROR)
val name = {
if(api.resourcePath == "") "[unknown]"
else api.resourcePath
}
for(a <- api.apis) {
validate(a, errors, name)
}
api.models match {
case Some(m) => for((name, model) <- m) {
validate(model, errors, name)
}
case None =>
}
}
def validate(model: Model, errors: ListBuffer[ValidationError], parent: String): Unit = {
if(model.id == "")
errors += ValidationError(parent + ":[model]", "id is required", ERROR)
}
def validate(desc: ApiDescription, errors: ListBuffer[ValidationError], parent: String): Unit = {
if(desc.path == "")
errors += ValidationError(parent + ":[api]", "path is required", ERROR)
for(op <- desc.operations)
validate(op, errors, parent + ":" + desc.path)
}
def validate(op: Operation, errors: ListBuffer[ValidationError], parent: String): Unit = {
if(op.method == "")
errors += ValidationError(parent + ":[operation]", "method is required", ERROR)
if(op.nickname == "")
errors += ValidationError(parent + ":" + op.method, "nickname is recommended", WARNING)
if(op.responseClass == "")
errors += ValidationError(parent + ":" + op.method, "responseClass is required", ERROR)
for(resp <- op.responseMessages)
validate(resp, errors, parent)
for(param <- op.parameters)
validate(param, errors, parent)
}
def validate(param: Parameter, errors: ListBuffer[ValidationError], parent: String): Unit = {
val name = if(param.name == "")
"[unknown]"
else
param.name
if(param.name == "")
errors += ValidationError(parent + ":[parameter]", "name is required", ERROR)
if(param.paramType == "")
errors += ValidationError(parent + name, "paramType is required", ERROR)
if(param.dataType == "")
errors += ValidationError(parent + name, "type is required", ERROR)
}
def validate(resp: ResponseMessage, errors: ListBuffer[ValidationError], parent: String): Unit = {
if(resp.code == 0)
errors += ValidationError(parent + ":[responseMessage]", "code is required", ERROR)
if(resp.message == 0)
errors += ValidationError(parent + ":[responseMessage]", "message is required", ERROR)
}
}

View File

@ -1,22 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.spec
object SwaggerSpec {
val primitives = List("int", "string", "long", "double", "float", "boolean", "void")
val containers = List("List", "Map", "Set", "Array")
}

View File

@ -1,446 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.spec
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.PathUtil
import com.wordnik.swagger.codegen.spec.SwaggerSpec._
import com.wordnik.swagger.codegen.util.CoreUtils
import java.util.logging.Logger
import String.format
import scala.collection.mutable.ListBuffer
import scala.collection.JavaConversions._
import org.fusesource.scalate.{ TemplateSource, TemplateEngine }
import java.io.{ FileWriter, File }
import scala.io.Source
import scala.collection.mutable.HashSet
import scala.collection.immutable.HashMap
class SwaggerSpecValidator(private val doc: ResourceListing,
private val apis: List[ApiListing],
private val fix: Boolean = true) extends PathUtil {
import ValidationMessage._
private val validationMessages = ListBuffer.empty[ValidationMessage]
private val LOGGER = Logger.getLogger(classOf[SwaggerSpecValidator].getName)
def validate() {
checkRootProperties()
apis.foreach(api => {
fixSubDoc(api)
api.models match {
case Some(models) => {
fixReturnModels(models.toMap, apis)
fixInputDataTypes(models.toMap, apis)
fixModels(models.toMap)
}
case None => LOGGER.warning("no models found for listing " + api.basePath)
}
})
validateResponseModels(apis)
println("----------")
println(this)
}
def validateResponseModels(subDocs: List[ApiListing]) = {
val validModelNames = CoreUtils.extractAllModels(subDocs).map(m => m._1).toSet
val requiredModels = new HashSet[String]
subDocs.foreach(subDoc => {
if (subDoc.apis != null) {
subDoc.apis.foreach(api => {
api.operations.foreach(op => {
requiredModels += {
val responseClass = op.responseClass
responseClass.indexOf("[") match {
case i: Int if (i > 0) => {
CoreUtils.extractBasePartFromType(responseClass)
}
case _ => responseClass
}
}
})
})
}
})
val missingModels = requiredModels.toSet -- (validModelNames ++ primitives)
if (missingModels.size > 0) println("missing models: " + missingModels)
}
def generateReport(host: String, outputFilename: Option[String]) {
outputFilename match {
case Some(o) => {
val rootDir = new java.io.File(".")
val engine = new TemplateEngine(Some(rootDir))
val templateLocation = "validator" + File.separator + "index.mustache"
val template = engine.compile(
TemplateSource.fromText(templateLocation, Source.fromInputStream(getClass.getClassLoader.getResourceAsStream(templateLocation)).mkString))
val output = engine.layout(templateLocation, template, HashMap(
"messages" -> validationMessages,
"host" -> host,
"basePath" -> doc.basePath,
"swaggerVersion" -> doc.swaggerVersion,
"apiVersion" -> doc.apiVersion))
val fw = new FileWriter(o, false)
fw.write(output + "\n")
fw.close()
println("wrote " + o)
}
case None =>
println("Output file location not passed as program argument")
}
}
/**
* Checks the swagger.version, basePath and api.version which is
* expected to be present in root resource listing
*
*/
private def checkRootProperties() {
doc.swaggerVersion match {
case e: String => println("swagger version: " + e)
case _ => !!(doc, RESOURCE_LISTING, "Properties", "Missing swagger version")
}
doc.basePath match {
case e: String => println("basePath: " + e)
case _ => !!(doc, RESOURCE_LISTING, "Properties", "Missing base path")
}
doc.apiVersion match {
case e: String => println("api version: " + e)
case _ => !!(doc, RESOURCE_LISTING, "Properties", "Missing api version", WARNING)
}
}
/**
* this is here because sub documents don't have the same resourcePath as declared in
* the main resource listing
*/
private def fixSubDoc(api: ApiListing) = {
if (api.resourcePath.indexOf(".{format}") == -1) {
doc.apis.foreach(op => {
if (op.path.indexOf(".{format}") > 0 && op.path.replaceAll(".\\{format\\}", "") == api.resourcePath) {
if (fix) {
api.resourcePath = api.resourcePath + ".{format}"
}
}
})
}
}
/**
* this is here because models don't have the proper references to types
*/
private def fixModels(models: Map[String, Model]) = {
val validModelNames = models.map(_._1).toSet
LOGGER.finest("all valid models: " + validModelNames)
for ((name, model) <- models) {
// id of model
getUpdatedType(validModelNames, model.id) match {
case Some(updatedType) => {
if (!model.id.equals(updatedType)) {
!!(model, MODEL, model.id, format("Invalid id. Best guess: %s", updatedType))
LOGGER.finest("updated " + model.id + " to " + updatedType)
if (fix) model.id = updatedType
}
}
case None => {
LOGGER.finest("can't find type for " + model.name + ", type " + model.id)
!!(model, MODEL, model.name, format("Missing type (%s)", model.id))
}
}
model.properties.foreach(prop => {
val subObjectName = prop._1
val subObject = prop._2
if (containers.contains(subObject.`type`)) {
// process the sub object
subObject.items match {
case Some(item) => {
getUpdatedType(validModelNames, item.ref.getOrElse(null)) match {
case Some(updatedType) => {
if (!item.ref.get.equals(updatedType)) {
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid ref (%s). Best guess: %s", item.ref, updatedType))
LOGGER.finest("updated subObject.items.ref " + item.ref + " to " + updatedType)
if (fix) {
subObject.items = Some(ModelRef(null, Some(updatedType)))
}
}
}
case None =>
}
}
case _ =>
}
} else if (containers.contains(subObject.`type`)) {
// process the sub object
if (subObject.items != null && subObject.items != None && subObject.items.get.ref != null){
subObject.items match {
case Some(item) => {
getUpdatedType(validModelNames, item.ref.getOrElse(null)) match {
case Some(updatedType) => {
if (!item.ref.equals(updatedType)) {
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid ref (%s). Best guess: %s", item.ref, updatedType))
LOGGER.finest("updated subObject.items.ref " + item.ref + " to " + updatedType)
if (fix) subObject.items = Some(ModelRef(null, Some(updatedType)))
}
}
case None => {
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid ref (%s).", item.ref))
LOGGER.finest("didn't know what to do with " + item.ref)
}
}
}
case _ =>
}
}
else if (subObject.items != null && subObject.items != None && subObject.items.get.`type` != null) {
subObject.items match {
case Some(item) => {
getUpdatedType(validModelNames, item.`type`) match {
case Some(updatedType) => {
if (!item.`type`.equals(updatedType)) {
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid type (%s). Best guess: %s", item.`type`, updatedType))
LOGGER.finest("updated subObject.items.type" + item.`type` + " to " + updatedType)
if (fix) subObject.items = Some(ModelRef(`type` = updatedType))
}
}
case None => {
println("nothing found for " + subObject)
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid ref (%s).", item.ref))
LOGGER.finest("didn't know what to do with " + item.ref)
}
}
}
case _ =>
}
}
} else {
getUpdatedType(validModelNames, subObject.`type`) match {
case Some(updatedType) => {
if (!subObject.`type`.equals(updatedType)) {
!!(model, MODEL_PROPERTY, format("%s->%s: %s", model.id, subObjectName, subObject.`type`), format("Invalid type (%s). Best guess: %s", subObject.`type`, updatedType))
LOGGER.finest("updated subObject.getType " + subObject.`type` + " to " + updatedType)
if (fix) subObject.`type` = updatedType
}
}
case None =>
}
}
})
// remove params with invalid names (Pos???)
model.properties = model.properties.filter(prop => {
if (prop._1.indexOf("$") == -1) true
else {
!!(model, MODEL, model.id, format("Invalid property %s. Removing it", prop._1))
LOGGER.finest("removing invalid property " + prop._1)
if (fix) false else true
}
})
}
}
/**
* this is here because input params in operations don't match primitives or model names
*/
private def fixInputDataTypes(models: Map[String, Model], a: List[ApiListing]) = {
val validModelNames = models.map(m => m._1).toSet
// List[ApiListing]
a.foreach(listing => {
if (listing.apis != null) {
listing.apis.foreach(api => {
// List[ApiDescription]
api.operations.foreach(op => {
// List[Operation]
val modelNames = new ListBuffer[String]
if(op.parameters != null) {
op.parameters.foreach(p => {
val dataType = p.dataType
p.paramType match {
case "body" => {
getUpdatedType(validModelNames, dataType) match {
case Some(updatedName) => {
if (!p.dataType.equals(updatedName)) {
// LOGGER.finest("--> updated " + dataType + " to " + updatedName)
!!(p, OPERATION_PARAM, format("%s.%s(body: %s)", apiNameFromPath(api.path), op.nickname, p.dataType), format("Invalid data type %s. Best guess: %s", p.dataType, updatedName))
if (fix) p.dataType = updatedName
}
}
case _ => LOGGER.finest("rats!") // leave it alone
}
}
case "path" => {
getUpdatedType(validModelNames, dataType) match {
case Some(updatedName) => {
// LOGGER.finest("--> updated " + dataType + " to " + updatedName)
!!(p, OPERATION_PARAM, format("%s.%s(path_%s: %s)", apiNameFromPath(api.path), op.nickname, p.name, p.dataType), format("Invalid data type %s. Best guess: %s", p.dataType, updatedName))
if (fix) p.dataType = updatedName
}
case _ => // leave it alone
}
}
case "query" => {
getUpdatedType(validModelNames, dataType) match {
case Some(updatedName) => {
// LOGGER.finest("--> updated " + dataType + " to " + updatedName)
!!(p, OPERATION_PARAM, format("%s.%s(query_%s: %s)", apiNameFromPath(api.path), op.nickname, p.name, p.dataType), format("Invalid %s. Best guess: %s", p.dataType, updatedName))
if (fix) p.dataType = updatedName
}
case _ => // leave it alone
}
}
case _ =>
}
})
}
})
})
}
})
}
/**
* this is here because the return types are inconsistent from the swagger-core-1.02-SNAPSHOT
*/
private def fixReturnModels(models: Map[String, Model], a: List[ApiListing]) = {
val validModelNames = models.map(m => m._1).toSet
// List[ApiListing]
a.foreach(listing => {
if (listing.apis != null) {
listing.apis.foreach(api => {
// List[ApiDescription]
api.operations.foreach(op => {
// List[Operation]
val responseClass = op.responseClass
if (responseClass != null) {
getUpdatedType(validModelNames, responseClass) match {
case Some(updatedName) => {
if (!responseClass.equals(updatedName)) {
LOGGER.finest("--> updated " + responseClass + " to " + updatedName)
!!(op, OPERATION, format("%s.%s(): %s", apiNameFromPath(api.path), op.nickname, op.responseClass), format("Invalid response class. Best guess: %s", updatedName))
if (fix) op.responseClass = updatedName
}
}
case _ => {
} // leave it alone
}
}
})
})
}
})
}
private def getUpdatedType(validModelNames: Set[String], name: String): Option[String] = {
if(name == null) return None
if (validModelNames.contains(name)) {
Some(name)
} else if (name.indexOf("[") > 0) {
// it's a complex value
val ComplexTypeMatcher = ".*\\[(.*)\\].*".r
val ComplexTypeMatcher(basePart) = name
getUpdatedType(validModelNames, basePart) match {
case Some(updatedPart) => {
Some(name.replaceAll(java.util.regex.Pattern.quote(basePart), updatedPart))
}
case _ => None
}
} else if (name.indexOf(".") > 0) {
val basePart = name.split("\\.").last
getUpdatedType(validModelNames, basePart) match {
case Some(updatedPart) => {
Some(updatedPart)
}
case _ => {
None
}
}
} else if (!primitives.contains(name)) {
val pc = name
if (validModelNames.contains(pc)) {
Some(pc)
} else if (pc == "Ok") {
Some("void")
} else if (pc == "Long") {
Some("long")
} else if (pc == "Double") {
Some("double")
} else if (pc == "Float") {
Some("float")
} else if (pc == "Boolean") {
Some("boolean")
} else if (pc == "Integer") {
Some("int")
} else if (pc == "Byte") {
Some("byte")
} else {
None
}
} else {
None
}
}
def !!(element: AnyRef, elementType: String, elementId: String, message: String, level: String = ERROR) {
validationMessages += new ValidationMessage(element, elementType, elementId, message, level)
}
override def toString = {
val out = new StringBuilder
for (v <- validationMessages) {
out.append(v)
out.append('\n')
}
out.toString()
}
}
class ValidationMessage(val element: AnyRef, val elementType: String, val elementId: String, val message: String, val level: String) {
override def toString = level + ": " + elementType + " - " + elementId + " | " + message
}
object ValidationMessage {
val WARNING = "Warning"
val ERROR = "Error"
val RESOURCE_LISTING = "Root Resources Listing"
val RESOURCE = "Resource"
val OPERATION = "Operation"
val OPERATION_PARAM = "Operation Parameter"
val MODEL = "Model"
val MODEL_PROPERTY = "Model Property"
val validationMessages = ListBuffer.empty[ValidationMessage]
}

View File

@ -1,69 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.spec
import com.wordnik.swagger.codegen.util.{CoreUtils, ApiExtractor, ResourceExtractor}
import com.wordnik.swagger.codegen.PathUtil
import com.wordnik.swagger.codegen.model._
import scala.collection.JavaConversions._
object Validator extends PathUtil {
def main(args: Array[String]) {
if(args.length == 0) {
throw new RuntimeException("Need url to Resource Listing as argument. You can also specify VM Argument -DfileMap=/path/to/resourceListing")
}
val host = args(0)
val fileMap = Option(sys.props("fileMap"))
val authorization = {
Option (System.getProperty("header")) match {
case Some(e) => {
// this is ugly and will be replaced with proper arg parsing like in ScalaAsyncClientGenerator soon
val authInfo = e.split(":")
Some(ApiKeyValue(authInfo(0), "header", authInfo(1)))
}
case _ => {
if (args.length > 1) {
Some(ApiKeyValue("api_key", "query", args(1)))
}
else None
}
}
}
val outputFilename = {
if (args.length > 2) Some(args(2))
else None
}
val doc = {
try {
ResourceExtractor.fetchListing(getResourcePath(host, fileMap), authorization)
} catch {
case e: Exception => throw new Exception("unable to read from " + host, e)
}
}
val basePath = getBasePath(host, doc.basePath, fileMap)
val apis = ApiExtractor.fetchApiListings(doc.swaggerVersion, basePath, doc.apis, authorization)
val swaggerSpecValidator = new SwaggerSpecValidator(doc, apis, false)
swaggerSpecValidator.validate()
swaggerSpecValidator.generateReport(host, outputFilename)
System.exit(0)
}
}

View File

@ -1,75 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.util
import com.wordnik.swagger.codegen.model._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.read
import java.net.URL
import java.io.InputStream
import scala.io._
import scala.collection.mutable.{ ListBuffer, HashMap, HashSet }
object ApiExtractor extends RemoteUrl {
def fetchApiListings(version: String, basePath: String, apis: List[ApiListingReference], authorization: Option[AuthorizationValue] = None): List[ApiListing] = {
implicit val formats = SwaggerSerializers.formats(version)
(for (api <- apis) yield {
try{
val json = (basePath.startsWith("http")) match {
case true => {
val path = if(api.path.startsWith("http")) api.path
else basePath + api.path
urlToString(path.replaceAll(".\\{format\\}", ".json"), authorization)
}
case false => Source.fromFile((basePath + api.path).replaceAll(".\\{format\\}", ".json")).mkString
}
Some(parse(json).extract[ApiListing])
}
catch {
case e: java.io.FileNotFoundException => {
println("WARNING! Unable to read API " + basePath + api.path)
None
}
case e: Throwable => {
println("WARNING! Unable to read API " + basePath + api.path)
e.printStackTrace()
None
}
}
}).flatten.toList
}
def extractApiOperations(version: String, basePath: String, references: List[ApiListingReference], authorization: Option[AuthorizationValue] = None) = {
implicit val formats = SwaggerSerializers.formats(version)
for (api <- references) yield {
val json = basePath.startsWith("http") match {
case true => {
urlToString((basePath + api.path).replaceAll(".\\{format\\}", ".json"), authorization)
}
case false => Source.fromFile((basePath + api.path).replaceAll(".\\{format\\}", ".json")).mkString
}
parse(json).extract[ApiListing]
}
}
def extractApiOperations(basePath: String, apiDescription: ApiDescription): List[(String, Operation)] = {
(for(op <- apiDescription.operations) yield (apiDescription.path, op)).toList
}
}

View File

@ -1,106 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.util
import com.wordnik.swagger.codegen.model._
import scala.collection.mutable.{ HashSet, ListBuffer, HashMap }
import scala.collection.JavaConversions._
import com.wordnik.swagger.codegen.spec.SwaggerSpec._
import scala.io.Source
import scala.collection.mutable
import scala.annotation.tailrec
object CoreUtils {
def extractAllModels(apis: List[ApiListing], excludes: Set[String] = Set.empty, typeMapping: Map[String, String] = Map.empty): Map[String, Model] = {
apis.foldLeft(Map.empty[String, Model]) { (acc, api) =>
acc ++ api.models.getOrElse(Map.empty[String, Model]) ++ extractApiModels(api, excludes, typeMapping)
}
}
def extractModelNames(op: Operation): Set[String] = {
// // POST, PUT, DELETE body
val modelNames = Set(op.responseClass) ++ op.parameters.filter(_.paramType == "body").map(_.dataType) ++ op.responseMessages.filter(!_.responseModel.isEmpty).map(_.responseModel.get)
modelNames map extractBasePartFromType
}
def extractBasePartFromType(datatype: String): String = {
val ComplexTypeMatcher = ".*\\[(.*)\\].*".r
datatype match {
case ComplexTypeMatcher(basePart) => basePart
case _ => datatype
}
}
def extractApiModels(sd: ApiListing, excludes: Set[String] = Set.empty, typeMapping: Map[String, String] = Map.empty): Map[String, Model] = {
def declNm(nm: String) =
typeMapping.foldLeft(nm)((n, kv) => ("\\b"+kv._1+"\\b").r.replaceAllIn(n, kv._2))
val modelObjects = sd.models.map(_.foldLeft(Map.empty[String, Model])(_ + _)) getOrElse Map.empty
// return types
val modelNames = sd.apis.foldLeft(Set.empty[String]) { (acc, api) =>
api.operations.foldLeft(acc){ _ ++ extractModelNames(_) }
}
// extract all base model names, strip away Containers like List[] and primitives
val baseNames = (modelNames filterNot primitives.contains) map extractBasePartFromType
// get complex models from base
val requiredModels = modelObjects.filter(obj => baseNames.contains(obj._1))
// look inside top-level models
val sn = subNames(requiredModels.toMap, modelObjects, Set.empty, typeMapping)
val subModels = modelObjects.filter(obj => sn.contains(obj._1))
val ex = excludes ++ primitives
for {
(k, v) <- requiredModels ++ subModels
if (!ex.contains(k))
} yield k -> v.copy(properties = v.properties.map(kv => kv._1 -> kv._2.copy(`type` = declNm(kv._2.`type`))))
}
def subNames(requiredModels: Map[String, Model], allModels: Map[String, Model], acc: Set[String] = Set.empty, typeMapping: Map[String, String]): Set[String] = {
requiredModels.foldLeft(acc) { case (subNames, (_, m)) =>
recurseModel(m.properties.toList, allModels, subNames + typeMapping.getOrElse(m.id, m.id), typeMapping)
}
}
@tailrec def recurseModel(properties: List[(String, ModelProperty)], allModels: Map[String, Model], subNames: Set[String], typeMapping: Map[String, String]): Set[String] = {
properties match {
case Nil =>
subNames
case (_, subObject) :: rest =>
val nm = subObject.`type`
def declNm(nm: String) =
typeMapping.foldLeft(nm)((n, kv) => ("\\b"+kv._1+"\\b").r.replaceAllIn(n, kv._2))
val propertyName = if (containers.contains(nm)) {
subObject.items flatMap (si => Option(si.ref.getOrElse(si.`type`)).map(declNm)) orElse Option(declNm(nm))
} else Option(declNm(nm))
if (propertyName.isDefined && !subNames.contains(propertyName.get)) {
val prop = propertyName.get
if (allModels.contains(prop)) {
val newSubnames = this.subNames(Map(prop -> allModels(prop)), allModels, subNames + prop, typeMapping)
recurseModel(rest, allModels, newSubnames, typeMapping)
} else {
val newSubnames = subNames + prop
recurseModel(rest, allModels, newSubnames, typeMapping)
}
} else recurseModel(rest, allModels, subNames, typeMapping)
}
}
}

View File

@ -1,46 +0,0 @@
package com.wordnik.swagger.codegen.util
import com.wordnik.swagger.codegen.model._
import java.net._
import java.io.InputStream
import scala.io.Source
trait RemoteUrl {
def urlToString(url: String, authorization: Option [AuthorizationValue]): String = {
var is: InputStream = null
try{
val conn: URLConnection = authorization match {
case Some(auth: ApiKeyValue) => {
if(auth.passAs == "header") {
val connection = new URL(url).openConnection()
connection.setRequestProperty(auth.keyName, auth.value)
connection
}
else if(auth.passAs == "query") {
new URL(url + "?%s=%s".format(URLEncoder.encode(auth.keyName), URLEncoder.encode(auth.value))).openConnection()
}
else {
new URL(url).openConnection()
}
}
case None => new URL(url).openConnection()
}
is = conn.getInputStream()
Source.fromInputStream(is).mkString
}
catch {
case e: javax.net.ssl.SSLProtocolException => {
println("there is a problem with the target SSL certificate")
println("**** you may want to run with -Djsse.enableSNIExtension=false\n\n")
e.printStackTrace
throw e
}
case e: Exception => e.printStackTrace; throw e;
}
finally {
if(is != null) is.close()
}
}
}

View File

@ -1,48 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.wordnik.swagger.codegen.util
import com.wordnik.swagger.codegen.model._
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.read
import scala.io._
object ResourceExtractor extends RemoteUrl {
def fetchListing(path: String, authorization: Option[AuthorizationValue] = None): ResourceListing = {
val json = path.startsWith("http") match {
case true => urlToString(path, authorization)
case false => Source.fromFile(path).mkString
}
implicit val formats = {
val jval = parse(json)
val version = (jval \ "swaggerVersion") match {
case e: JInt => e.num.toString
case e: JBool => e.value.toString
case e: JString => e.s
case e: JDouble => e.num.toString
case _ => ""
}
SwaggerSerializers.formats(version)
}
parse(json).extract[ResourceListing]
}
}

View File

@ -1,24 +0,0 @@
package com.wordnik.swagger.util
import com.wordnik.swagger.codegen.model._
import scala.collection.JavaConverters._
import scala.beans.BeanProperty
class ValidationException(code:Int, msg:String, errors: List[ValidationError]) extends Exception(msg:String) {
val messages: java.util.List[ValidationMessage] = (
for(e <- errors) yield ({
val m = new ValidationMessage()
m.path = e.path
m.message = e.message
m.severity = e.severity
m
})
).toList.asJava
}
class ValidationMessage() {
@BeanProperty var path: String = _
@BeanProperty var message: String = _
@BeanProperty var severity: String = _
}

View File

@ -1,227 +0,0 @@
{
"apiVersion":"0.2",
"swaggerVersion":"1.1",
"basePath":"http://petstore.swagger.wordnik.com/api",
"resourcePath":"/pet",
"apis":[
{
"path":"/pet.{format}/{petId}",
"description":"Operations about pets",
"operations":[
{
"httpMethod":"GET",
"summary":"Find pet by ID",
"notes":"Returns a pet based on ID",
"responseClass":"Pet",
"nickname":"getPetById",
"parameters":[
{
"name":"petId",
"description":"ID of pet that needs to be fetched",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid ID supplied"
},
{
"code":404,
"reason":"Pet not found"
}
]
}
]
},
{
"path":"/pet.{format}",
"description":"Operations about pets",
"operations":[
{
"httpMethod":"POST",
"summary":"Add a new pet to the store",
"responseClass":"void",
"nickname":"addPet",
"parameters":[
{
"description":"Pet object that needs to be added to the store",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"Pet"
}
],
"errorResponses":[
{
"code":405,
"reason":"Invalid input"
}
]
},
{
"httpMethod":"PUT",
"summary":"Update an existing pet",
"responseClass":"void",
"nickname":"updatePet",
"parameters":[
{
"description":"Pet object that needs to be updated in the store",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"Pet"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid ID supplied"
},
{
"code":404,
"reason":"Pet not found"
},
{
"code":405,
"reason":"Validation exception"
}
]
}
]
},
{
"path":"/pet.{format}/findByStatus",
"description":"Operations about pets",
"operations":[
{
"httpMethod":"GET",
"summary":"Finds Pets by status",
"notes":"Multiple status values can be provided with comma seperated strings",
"responseClass":"List[Pet]",
"nickname":"findPetsByStatus",
"parameters":[
{
"name":"status",
"description":"Status values that need to be considered for filter",
"paramType":"query",
"defaultValue":"available",
"allowableValues":{
"valueType":"LIST",
"values":[
"available",
"pending",
"sold"
]
},
"required":true,
"allowMultiple":true,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid status value"
}
]
}
]
},
{
"path":"/pet.{format}/findByTags",
"description":"Operations about pets",
"operations":[
{
"httpMethod":"GET",
"summary":"Finds Pets by tags",
"notes":"Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
"deprecated":true,
"responseClass":"List[Pet]",
"nickname":"findPetsByTags",
"parameters":[
{
"name":"tags",
"description":"Tags to filter by",
"paramType":"query",
"required":true,
"allowMultiple":true,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid tag value"
}
]
}
]
}
],
"models":{
"Category":{
"id":"Category",
"properties":{
"id":{
"type":"long"
},
"name":{
"type":"string"
}
}
},
"Pet":{
"id":"Pet",
"properties":{
"tags":{
"items":{
"$ref":"Tag"
},
"type":"Array"
},
"id":{
"type":"long"
},
"category":{
"type":"Category"
},
"status":{
"allowableValues":{
"valueType":"LIST",
"values":[
"available",
"pending",
"sold"
]
},
"description":"pet status in the store",
"type":"string"
},
"name":{
"type":"string"
},
"photoUrls":{
"items":{
"type":"string"
},
"type":"Array"
}
}
},
"Tag":{
"id":"Tag",
"properties":{
"id":{
"type":"long"
},
"name":{
"type":"string"
}
}
}
}
}

View File

@ -1,19 +0,0 @@
{
"apiVersion":"0.2",
"swaggerVersion":"1.1",
"basePath":"http://petstore.swagger.wordnik.com/api",
"apis":[
{
"path":"/store.{format}",
"description":"Operations about store"
},
{
"path":"/pet.{format}",
"description":"Operations about pets"
},
{
"path":"/user.{format}",
"description":"Operations about user"
}
]
}

View File

@ -1,127 +0,0 @@
{
"apiVersion":"0.2",
"swaggerVersion":"1.1",
"basePath":"http://petstore.swagger.wordnik.com/api",
"resourcePath":"/store",
"apis":[
{
"path":"/store.{format}/order/{orderId}",
"description":"Operations about store",
"operations":[
{
"httpMethod":"GET",
"summary":"Find purchase order by ID",
"notes":"For valid response try integer IDs with value <= 5. Anything above 5 or nonintegers will generate API errors",
"responseClass":"Order",
"nickname":"getOrderById",
"parameters":[
{
"name":"orderId",
"description":"ID of pet that needs to be fetched",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid ID supplied"
},
{
"code":404,
"reason":"Order not found"
}
]
},
{
"httpMethod":"DELETE",
"summary":"Delete purchase order by ID",
"notes":"For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
"responseClass":"void",
"nickname":"deleteOrder",
"parameters":[
{
"name":"orderId",
"description":"ID of the order that needs to be deleted",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid ID supplied"
},
{
"code":404,
"reason":"Order not found"
}
]
}
]
},
{
"path":"/store.{format}/order",
"description":"Operations about store",
"operations":[
{
"httpMethod":"POST",
"summary":"Place an order for a pet",
"responseClass":"void",
"nickname":"placeOrder",
"parameters":[
{
"description":"order placed for purchasing the pet",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"Order"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid order"
}
]
}
]
}
],
"models":{
"Order":{
"id":"Order",
"properties":{
"id":{
"type":"long"
},
"petId":{
"type":"long"
},
"status":{
"allowableValues":{
"valueType":"LIST",
"values":[
"placed",
" approved",
" delivered"
],
"valueType":"LIST"
},
"description":"Order Status",
"type":"string"
},
"quantity":{
"type":"int"
},
"shipDate":{
"type":"Date"
}
}
}
}
}

View File

@ -1,254 +0,0 @@
{
"apiVersion":"0.2",
"swaggerVersion":"1.1",
"basePath":"http://petstore.swagger.wordnik.com/api",
"resourcePath":"/user",
"apis":[
{
"path":"/user.{format}/createWithArray",
"description":"Operations about user",
"operations":[
{
"httpMethod":"POST",
"summary":"Creates list of users with given input array",
"responseClass":"void",
"nickname":"createUsersWithArrayInput",
"parameters":[
{
"description":"List of user object",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"Array[User]"
}
]
}
]
},
{
"path":"/user.{format}",
"description":"Operations about user",
"operations":[
{
"httpMethod":"POST",
"summary":"Create user",
"notes":"This can only be done by the logged in user.",
"responseClass":"void",
"nickname":"createUser",
"parameters":[
{
"description":"Created user object",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"User"
}
]
}
]
},
{
"path":"/user.{format}/createWithList",
"description":"Operations about user",
"operations":[
{
"httpMethod":"POST",
"summary":"Creates list of users with given list input",
"responseClass":"void",
"nickname":"createUsersWithListInput",
"parameters":[
{
"description":"List of user object",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"List[User]"
}
]
}
]
},
{
"path":"/user.{format}/{username}",
"description":"Operations about user",
"operations":[
{
"httpMethod":"PUT",
"summary":"Updated user",
"notes":"This can only be done by the logged in user.",
"responseClass":"void",
"nickname":"updateUser",
"parameters":[
{
"name":"username",
"description":"name that need to be deleted",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"string"
},
{
"description":"Updated user object",
"paramType":"body",
"required":true,
"allowMultiple":false,
"dataType":"User"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid username supplied"
},
{
"code":404,
"reason":"User not found"
}
]
},
{
"httpMethod":"DELETE",
"summary":"Delete user",
"notes":"This can only be done by the logged in user.",
"responseClass":"void",
"nickname":"deleteUser",
"parameters":[
{
"name":"username",
"description":"The name that needs to be deleted",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid username supplied"
},
{
"code":404,
"reason":"User not found"
}
]
},
{
"httpMethod":"GET",
"summary":"Get user by user name",
"responseClass":"User",
"nickname":"getUserByName",
"parameters":[
{
"name":"username",
"description":"The name that needs to be fetched. Use user1 for testing.",
"paramType":"path",
"required":true,
"allowMultiple":false,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid username supplied"
},
{
"code":404,
"reason":"User not found"
}
]
}
]
},
{
"path":"/user.{format}/login",
"description":"Operations about user",
"operations":[
{
"httpMethod":"GET",
"summary":"Logs user into the system",
"responseClass":"string",
"nickname":"loginUser",
"parameters":[
{
"name":"username",
"description":"The user name for login",
"paramType":"query",
"required":true,
"allowMultiple":false,
"dataType":"string"
},
{
"name":"password",
"description":"The password for login in clear text",
"paramType":"query",
"required":true,
"allowMultiple":false,
"dataType":"string"
}
],
"errorResponses":[
{
"code":400,
"reason":"Invalid username and password combination"
}
]
}
]
},
{
"path":"/user.{format}/logout",
"description":"Operations about user",
"operations":[
{
"httpMethod":"GET",
"summary":"Logs out current logged in user session",
"responseClass":"void",
"nickname":"logoutUser"
}
]
}
],
"models":{
"User":{
"id":"User",
"properties":{
"id":{
"type":"long"
},
"lastName":{
"type":"string"
},
"phone":{
"type":"string"
},
"username":{
"type":"string"
},
"email":{
"type":"string"
},
"userStatus":{
"allowableValues":{
"valueType":"LIST",
"values":[
"1-registered",
"2-active",
"3-closed"
],
"valueType":"LIST"
},
"description":"User Status",
"type":"int"
},
"firstName":{
"type":"string"
},
"password":{
"type":"string"
}
}
}
}
}

View File

@ -1,60 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"apis": [
{
"path": "/pet",
"description": "Operations about pets"
},
{
"path": "/user",
"description": "Operations about user"
},
{
"path": "/store",
"description": "Operations about store"
}
],
"authorizations": {
"oauth2": {
"type": "oauth2",
"scopes": [
{
"scope": "email",
"description": "Access to your email address"
},
{
"scope": "pets",
"description": "Access to your pets"
}
],
"grantTypes": {
"implicit": {
"loginEndpoint": {
"url": "http://petstore.swagger.wordnik.com/oauth/dialog"
},
"tokenName": "access_token"
},
"authorization_code": {
"tokenRequestEndpoint": {
"url": "http://petstore.swagger.wordnik.com/oauth/requestToken",
"clientIdName": "client_id",
"clientSecretName": "client_secret"
},
"tokenEndpoint": {
"url": "http://petstore.swagger.wordnik.com/oauth/token",
"tokenName": "access_code"
}
}
}
}
},
"info": {
"title": "Swagger Sample App",
"description": "This is a sample server Petstore server. You can find out more about Swagger \n at <a href=\"http://swagger.wordnik.com\">http://swagger.wordnik.com</a> or on irc.freenode.net, #swagger. For this sample,\n you can use the api key \"special-key\" to test the authorization filters",
"termsOfServiceUrl": "http://helloreverb.com/terms/",
"contact": "apiteam@wordnik.com",
"license": "Apache 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
}

View File

@ -1,425 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://petstore.swagger.wordnik.com/api",
"resourcePath": "/pet",
"produces": [
"application/json",
"application/xml",
"text/plain",
"text/html"
],
"apis": [
{
"path": "/pet/{petId}",
"operations": [
{
"method": "GET",
"summary": "Find pet by ID",
"notes": "Returns a pet based on ID",
"type": "Pet",
"nickname": "getPetById",
"authorizations": {},
"parameters": [
{
"name": "petId",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "integer",
"format": "int64",
"paramType": "path",
"minimum": "1.0",
"maximum": "100000.0"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid ID supplied"
},
{
"code": 404,
"message": "Pet not found"
}
]
},
{
"method": "PATCH",
"summary": "partial updates to a pet",
"notes": "",
"type": "array",
"items": {
"$ref": "Pet"
},
"nickname": "partialUpdate",
"produces": [
"application/json",
"application/xml"
],
"consumes": [
"application/json",
"application/xml"
],
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "petId",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": true,
"type": "Pet",
"paramType": "body"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid tag value"
}
]
},
{
"method": "POST",
"summary": "Updates a pet in the store with form data",
"notes": "",
"type": "void",
"nickname": "updatePetWithForm",
"consumes": [
"application/x-www-form-urlencoded"
],
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "petId",
"description": "ID of pet that needs to be updated",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "name",
"description": "Updated name of the pet",
"required": false,
"type": "string",
"paramType": "form"
},
{
"name": "status",
"description": "Updated status of the pet",
"required": false,
"type": "string",
"paramType": "form"
}
],
"responseMessages": [
{
"code": 405,
"message": "Invalid input"
}
]
},
{
"method": "DELETE",
"summary": "Deletes a pet",
"notes": "",
"type": "void",
"nickname": "deletePet",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "petId",
"description": "Pet id to delete",
"required": true,
"type": "string",
"paramType": "path"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid pet value"
}
]
}
]
},
{
"path": "/pet",
"operations": [
{
"method": "PUT",
"summary": "Update an existing pet",
"notes": "",
"type": "void",
"nickname": "updatePet",
"authorizations": {},
"parameters": [
{
"name": "body",
"description": "Pet object that needs to be updated in the store",
"required": true,
"type": "Pet",
"paramType": "body"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid ID supplied"
},
{
"code": 404,
"message": "Pet not found"
},
{
"code": 405,
"message": "Validation exception"
}
]
},
{
"method": "POST",
"summary": "Add a new pet to the store",
"notes": "",
"type": "void",
"nickname": "addPet",
"consumes": [
"application/json",
"application/xml"
],
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": true,
"type": "Pet",
"paramType": "body"
}
],
"responseMessages": [
{
"code": 405,
"message": "Invalid input"
}
]
}
]
},
{
"path": "/pet/findByStatus",
"operations": [
{
"method": "GET",
"summary": "Finds Pets by status",
"notes": "Multiple status values can be provided with comma seperated strings",
"type": "array",
"items": {
"$ref": "Pet"
},
"nickname": "findPetsByStatus",
"authorizations": {},
"parameters": [
{
"name": "status",
"description": "Status values that need to be considered for filter",
"defaultValue": "available",
"required": true,
"type": "string",
"paramType": "query",
"enum": [
"available",
"pending",
"sold"
]
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid status value"
}
]
}
]
},
{
"path": "/pet/findByTags",
"operations": [
{
"method": "GET",
"summary": "Finds Pets by tags",
"notes": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
"type": "array",
"items": {
"$ref": "Pet"
},
"nickname": "findPetsByTags",
"authorizations": {},
"parameters": [
{
"name": "tags",
"description": "Tags to filter by",
"required": true,
"type": "string",
"paramType": "query"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid tag value"
}
],
"deprecated": "true"
}
]
},
{
"path": "/pet/uploadImage",
"operations": [
{
"method": "POST",
"summary": "uploads an image",
"notes": "",
"type": "void",
"nickname": "uploadFile",
"consumes": [
"multipart/form-data"
],
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
},
{
"scope": "test:nothing",
"description": "nothing"
}
]
},
"parameters": [
{
"name": "additionalMetadata",
"description": "Additional data to pass to server",
"required": false,
"type": "string",
"paramType": "form"
},
{
"name": "file",
"description": "file to upload",
"required": false,
"type": "File",
"paramType": "body"
}
]
}
]
}
],
"models": {
"Tag": {
"id": "Tag",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
},
"Pet": {
"id": "Pet",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64",
"description": "unique identifier for the pet",
"minimum": "0.0",
"maximum": "100.0"
},
"category": {
"$ref": "Category"
},
"name": {
"type": "string"
},
"photoUrls": {
"type": "array",
"items": {
"type": "string"
}
},
"tags": {
"type": "array",
"items": {
"$ref": "Tag"
}
},
"status": {
"type": "string",
"description": "pet status in the store",
"enum": [
"available",
"pending",
"sold"
]
}
}
},
"Category": {
"id": "Category",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
}
}
}
}

View File

@ -1,144 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://petstore.swagger.wordnik.com/api",
"resourcePath": "/store",
"produces": [
"application/json"
],
"apis": [
{
"path": "/store/order/{orderId}",
"operations": [
{
"method": "GET",
"summary": "Find purchase order by ID",
"notes": "For valid response try integer IDs with value <= 5. Anything above 5 or nonintegers will generate API errors",
"type": "Order",
"nickname": "getOrderById",
"authorizations": {},
"parameters": [
{
"name": "orderId",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "string",
"paramType": "path"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid ID supplied"
},
{
"code": 404,
"message": "Order not found"
}
]
},
{
"method": "DELETE",
"summary": "Delete purchase order by ID",
"notes": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
"type": "void",
"nickname": "deleteOrder",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "orderId",
"description": "ID of the order that needs to be deleted",
"required": true,
"type": "string",
"paramType": "path"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid ID supplied"
},
{
"code": 404,
"message": "Order not found"
}
]
}
]
},
{
"path": "/store/order",
"operations": [
{
"method": "POST",
"summary": "Place an order for a pet",
"notes": "",
"type": "void",
"nickname": "placeOrder",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "body",
"description": "order placed for purchasing the pet",
"required": true,
"type": "Order",
"paramType": "body"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid order"
}
]
}
]
}
],
"models": {
"Order": {
"id": "Order",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"petId": {
"type": "integer",
"format": "int64"
},
"quantity": {
"type": "integer",
"format": "int32"
},
"status": {
"type": "string",
"description": "Order Status",
"enum": [
"placed",
" approved",
" delivered"
]
},
"shipDate": {
"type": "string",
"format": "date-time"
}
}
}
}
}

View File

@ -1,299 +0,0 @@
{
"apiVersion": "1.0.0",
"swaggerVersion": "1.2",
"basePath": "http://petstore.swagger.wordnik.com/api",
"resourcePath": "/user",
"produces": [
"application/json"
],
"apis": [
{
"path": "/user",
"operations": [
{
"method": "POST",
"summary": "Create user",
"notes": "This can only be done by the logged in user.",
"type": "void",
"nickname": "createUser",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "body",
"description": "Created user object",
"required": true,
"type": "User",
"paramType": "body"
}
]
}
]
},
{
"path": "/user/logout",
"operations": [
{
"method": "GET",
"summary": "Logs out current logged in user session",
"notes": "",
"type": "void",
"nickname": "logoutUser",
"authorizations": {},
"parameters": []
}
]
},
{
"path": "/user/createWithArray",
"operations": [
{
"method": "POST",
"summary": "Creates list of users with given input array",
"notes": "",
"type": "void",
"nickname": "createUsersWithArrayInput",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "body",
"description": "List of user object",
"required": true,
"type": "array",
"items": {
"$ref": "User"
},
"paramType": "body"
}
]
}
]
},
{
"path": "/user/createWithList",
"operations": [
{
"method": "POST",
"summary": "Creates list of users with given list input",
"notes": "",
"type": "void",
"nickname": "createUsersWithListInput",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "body",
"description": "List of user object",
"required": true,
"type": "array",
"items": {
"$ref": "User"
},
"paramType": "body"
}
]
}
]
},
{
"path": "/user/{username}",
"operations": [
{
"method": "PUT",
"summary": "Updated user",
"notes": "This can only be done by the logged in user.",
"type": "void",
"nickname": "updateUser",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "username",
"description": "name that need to be deleted",
"required": true,
"type": "string",
"paramType": "path"
},
{
"name": "body",
"description": "Updated user object",
"required": true,
"type": "User",
"paramType": "body"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid username supplied"
},
{
"code": 404,
"message": "User not found"
}
]
},
{
"method": "DELETE",
"summary": "Delete user",
"notes": "This can only be done by the logged in user.",
"type": "void",
"nickname": "deleteUser",
"authorizations": {
"oauth2": [
{
"scope": "test:anything",
"description": "anything"
}
]
},
"parameters": [
{
"name": "username",
"description": "The name that needs to be deleted",
"required": true,
"type": "string",
"paramType": "path"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid username supplied"
},
{
"code": 404,
"message": "User not found"
}
]
},
{
"method": "GET",
"summary": "Get user by user name",
"notes": "",
"type": "User",
"nickname": "getUserByName",
"authorizations": {},
"parameters": [
{
"name": "username",
"description": "The name that needs to be fetched. Use user1 for testing.",
"required": true,
"type": "string",
"paramType": "path"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid username supplied"
},
{
"code": 404,
"message": "User not found"
}
]
}
]
},
{
"path": "/user/login",
"operations": [
{
"method": "GET",
"summary": "Logs user into the system",
"notes": "",
"type": "string",
"nickname": "loginUser",
"authorizations": {},
"parameters": [
{
"name": "username",
"description": "The user name for login",
"required": true,
"type": "string",
"paramType": "query"
},
{
"name": "password",
"description": "The password for login in clear text",
"required": true,
"type": "string",
"paramType": "query"
}
],
"responseMessages": [
{
"code": 400,
"message": "Invalid username and password combination"
}
]
}
]
}
],
"models": {
"User": {
"id": "User",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"firstName": {
"type": "string"
},
"username": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "integer",
"format": "int32",
"description": "User Status",
"enum": [
"1-registered",
"2-active",
"3-closed"
]
}
}
}
}
}

View File

@ -1,48 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.{BasicCSharpGenerator, PathUtil}
import com.wordnik.swagger.codegen.util._
import com.wordnik.swagger.codegen.language._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.beans.BeanProperty
@RunWith(classOf[JUnitRunner])
class BasicCSharpGeneratorTest extends FlatSpec with Matchers {
val config = new BasicCSharpGenerator
behavior of "BasicCSharpGenerator"
/*
* A response of type "void" will turn into a declaration of None
* for the template generator
*/
it should "perserve the name date" in {
config.toVarName("date") should be ("date")
}
/*
* arrays look nice
*/
it should "process a string array" in {
config.processResponseDeclaration("array[string]") should be (Some("List<string>"))
}
}

View File

@ -1,152 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.BasicGenerator
import com.wordnik.swagger.codegen.util._
import com.wordnik.swagger.codegen.model._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.mutable.{LinkedHashMap, HashMap}
@RunWith(classOf[JUnitRunner])
class BasicGeneratorTest extends FlatSpec with Matchers {
class SampleGenerator extends BasicGenerator {
modelTemplateFiles += "model.mustache" -> ".test"
override def typeMapping = Map(
"string" -> "String",
"int" -> "Int",
"float" -> "Float",
"long" -> "Long",
"double" -> "Double",
"object" -> "Any")
}
behavior of "BasicGenerator"
it should "get operations" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json")
val subDocs = ApiExtractor.fetchApiListings(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val allModels = new HashMap[String, Model]
implicit val basePath = "http://localhost:8080/api"
val generator = new SampleGenerator
val ops = generator.extractApiOperations(subDocs, allModels)
allModels.size should be (5)
ops.size should be (16)
val operations = ops.map(op => (op._2, op._3)).toMap
(operations.keys.toSet &
Set("/pet.{format}/findByTags", "/user.{format}/createWithArray", "/user.{format}/createWithList",
"/store.{format}/order", "/user.{format}", "/pet.{format}/findByStatus", "/user.{format}/{username}",
"/user.{format}/logout", "/user.{format}/login", "/pet.{format}/{petId}", "/store.{format}/order/{orderId}",
"/pet.{format}")).size should be (12)
// pick apart the /store/order api
val orderApi = operations("/store.{format}/order")
orderApi.method should be ("POST")
orderApi.summary should be ("Place an order for a pet")
orderApi.responseClass should be ("void")
orderApi.nickname should be ("placeOrder")
orderApi.parameters.size should be (1)
orderApi.responseMessages.size should be (1)
}
it should "verify ops are grouped by path correctly" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json")
val subDocs = ApiExtractor.fetchApiListings(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val allModels = new HashMap[String, Model]()
implicit val basePath = "http://localhost:8080/api"
val generator = new SampleGenerator
val ops = generator.extractApiOperations(subDocs, allModels)
val apiMap = generator.groupOperationsToFiles(ops)
// verify all apis are there
(apiMap.keys.map(m => m._2).toSet & Set("user", "pet", "store")).size should be (3)
// inspect the store apis
val orderApis = apiMap("http://petstore.swagger.wordnik.com/api","store").groupBy(_._1).toMap
val orderOperations = orderApis("/store.{format}/order/{orderId}").map(m => m._2)
// 2 operations
orderOperations.size should be (2)
(orderOperations.map(m => m.method).toSet & Set("GET", "DELETE")).size should be (2)
(orderOperations.map(m => m.nickname).toSet & Set("getOrderById", "deleteOrder")).size should be (2)
}
it should "create a model map" in {
implicit val basePath = "http://localhost:8080/api"
val generator = new SampleGenerator
val model = sampleModel
val bundle = generator.prepareModelMap(Map(model.id -> model)).head
// inspect properties
bundle("name") should be ("SampleObject")
bundle("className") should be ("SampleObject")
bundle("invokerPackage") should be (Some("com.wordnik.client.common"))
bundle("package") should be (Some("com.wordnik.client.model"))
// inspect models
val modelList = bundle("models").asInstanceOf[List[Map[String, AnyRef]]]
modelList.size should be (1)
val m = modelList.head("model").asInstanceOf[Map[String, AnyRef]]
m("classVarName") should be ("SampleObject")
}
it should "create a model file" in {
implicit val basePath = "http://localhost:8080/api"
val generator = new SampleGenerator
val model = sampleModel
val modelMap = (generator.prepareModelMap(Map(model.id -> model)))
val modelFileContents = generator.writeFiles(modelMap, generator.modelTemplateFiles.toMap).toMap
val name = modelFileContents.keys.filter(_.endsWith("SampleObject.test")).head
val fileContents = modelFileContents(name)
fileContents.indexOf("case class SampleObject") should not be (-1)
fileContents.indexOf("longValue: Long") should not be (-1)
fileContents.indexOf("intValue: Int") should not be (-1)
fileContents.indexOf("doubleValue: Double") should not be (-1)
fileContents.indexOf("stringValue: String") should not be (-1)
fileContents.indexOf("floatValue: Float") should not be (-1)
}
def sampleModel = {
Model(
"SampleObject",
"SampleObject",
"SampleObject",
LinkedHashMap(
"stringValue" -> ModelProperty("string", "java.lang.String"),
"intValue" -> ModelProperty("int", "int"),
"longValue" -> ModelProperty("long", "long"),
"floatValue" -> ModelProperty("float", "float"),
"doubleValue" -> ModelProperty("double", "double")),
Some("a sample object"))
}
}

View File

@ -1,204 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.{BasicJavaGenerator, PathUtil}
import com.wordnik.swagger.codegen.util._
import com.wordnik.swagger.codegen.language._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.beans.BeanProperty
@RunWith(classOf[JUnitRunner])
class BasicJavaGeneratorTest extends FlatSpec with Matchers {
val config = new BasicJavaGenerator
behavior of "BasicJavaGenerator"
/*
* A response of type "void" will turn into a declaration of None
* for the template generator
*/
it should "process a response declaration" in {
config.processResponseDeclaration("void") should be (None)
}
/*
* swagger strings are turned into scala Strings
*/
it should "process a string response" in {
config.processResponseDeclaration("string") should be (Some("String"))
}
/*
* arrays look nice
*/
it should "process a string array" in {
config.processResponseDeclaration("array[String]") should be (Some("List<String>"))
}
it should "process an upper-case string array" in {
config.processResponseDeclaration("Array[String]") should be (Some("List<String>"))
}
/*
* swagger int is turned into scala Int
*/
it should "process an unmapped response type" in {
config.processResponseDeclaration("int") should be (Some("Integer"))
}
/*
* returns the invoker package from the config
*/
it should "get the invoker package" in {
config.invokerPackage should be (Some("com.wordnik.client.common"))
}
/*
* returns the api package
*/
it should "get the api package" in {
config.apiPackage should be (Some("com.wordnik.client.api"))
}
/*
* returns the model package
*/
it should "get the model package" in {
config.modelPackage should be (Some("com.wordnik.client.model"))
}
/*
* types are mapped between swagger types and language-specific
* types
*/
it should "convert to a declared type" in {
config.toDeclaredType("string") should be ("String")
config.toDeclaredType("int") should be ("Integer")
config.toDeclaredType("float") should be ("Float")
config.toDeclaredType("long") should be ("Long")
config.toDeclaredType("double") should be ("Double")
config.toDeclaredType("object") should be ("Object")
}
/*
* declarations are used in models, and types need to be
* mapped appropriately
*/
it should "convert a string a declaration" in {
val expected = Map(
"string" -> ("String", "null"),
"int" -> ("Integer", "null"),
"float" -> ("Float", "null"),
"long" -> ("Long", "null"),
"double" -> ("Double", "null"),
"object" -> ("Object", "null"))
expected.map(e => {
val model = ModelProperty(e._1, "nothing")
config.toDeclaration(model) should be (e._2)
})
}
/*
* codegen should honor special imports to avoid generating
* classes
*/
it should "honor the import mapping" in {
config.importMapping("Date") should be ("java.util.Date")
config.importMapping("DateTime") should be ("org.joda.time.*")
config.importMapping("Timestamp") should be ("java.sql.Timestamp")
config.importMapping("Set") should be ("java.util.*")
}
/*
* fail on reserved words (java doesn't allow quoting)
*/
it should "quote a reserved var name" in {
val thrown = intercept[Exception] {
config.toVarName("package")
}
thrown should not be (null)
}
/*
* support list declarations with string inner value and the correct default value
*/
it should "create a declaration with a List of strings" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "string")))
val m = config.toDeclaration(property)
m._1 should be ("List<String>")
m._2 should be ("new ArrayList<String>()")
}
/*
* support list declarations with int inner value and the correct default value
*/
it should "create a declaration with a List of ints" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "int")))
val m = config.toDeclaration(property)
m._1 should be ("List<Integer>")
m._2 should be ("new ArrayList<Integer>()")
}
/*
* support list declarations with float inner value and the correct default value
*/
it should "create a declaration with a List of floats" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "float")))
val m = config.toDeclaration(property)
m._1 should be ("List<Float>")
m._2 should be ("new ArrayList<Float>()")
}
/*
* support list declarations with double inner value and the correct default value
*/
it should "create a declaration with a List of doubles" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "double")))
val m = config.toDeclaration(property)
m._1 should be ("List<Double>")
m._2 should be ("new ArrayList<Double>()")
}
/*
* support list declarations with complex inner value and the correct default value
*/
it should "create a declaration with a List of complex objects" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "User")))
val m = config.toDeclaration(property)
m._1 should be ("List<User>")
m._2 should be ("new ArrayList<User>()")
}
}

View File

@ -1,296 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.{BasicScalaGenerator, Codegen, PathUtil}
import com.wordnik.swagger.codegen.util._
import com.wordnik.swagger.codegen.language._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.mutable.HashMap
@RunWith(classOf[JUnitRunner])
class BasicScalaGeneratorTest extends FlatSpec with Matchers {
val config = new BasicScalaGenerator
behavior of "BasicScalaGenerator"
/*
* A response of type "void" will turn into a declaration of None
* for the template generator
*/
it should "process a response declaration" in {
config.processResponseDeclaration("void") should be (None)
}
/*
* swagger strings are turned into scala Strings
*/
it should "process a string response" in {
config.processResponseDeclaration("string") should be (Some("String"))
}
/*
* arrays look nice
*/
it should "process a string array" in {
config.processResponseDeclaration("array[String]") should be (Some("List[String]"))
}
/*
* swagger int is turned into scala Int
*/
it should "process an unmapped response type" in {
config.processResponseDeclaration("int") should be (Some("Int"))
}
/*
* returns the invoker package from the config
*/
it should "get the invoker package" in {
config.invokerPackage should be (Some("com.wordnik.client.common"))
}
/*
* returns the api package
*/
it should "get the api package" in {
config.apiPackage should be (Some("com.wordnik.client.api"))
}
/*
* returns the model package
*/
it should "get the model package" in {
config.modelPackage should be (Some("com.wordnik.client.model"))
}
/*
* types are mapped between swagger types and language-specific
* types
*/
it should "convert to a declared type" in {
config.toDeclaredType("boolean") should be ("Boolean")
config.toDeclaredType("string") should be ("String")
config.toDeclaredType("int") should be ("Int")
config.toDeclaredType("float") should be ("Float")
config.toDeclaredType("long") should be ("Long")
config.toDeclaredType("double") should be ("Double")
config.toDeclaredType("object") should be ("Any")
}
/*
* declarations are used in models, and types need to be
* mapped appropriately
*/
it should "convert a string a declaration" in {
val expected = Map("string" -> ("String", "_"),
"int" -> ("Int", "0"),
"float" -> ("Float", "0f"),
"long" -> ("Long", "0L"),
"double" -> ("Double", "0.0"),
"object" -> ("Any", "_"))
expected.map(e => {
val model = ModelProperty(e._1, "nothing")
config.toDeclaration(model) should be (e._2)
})
}
/*
* codegen should honor special imports to avoid generating
* classes
*/
it should "honor the import mapping" in {
config.importMapping("Date") should be ("java.util.Date")
}
/*
* single tick reserved words
*/
it should "quote a reserved var name" in {
config.toVarName("package") should be ("`package`")
}
/*
* support list declarations with string inner value and the correct default value
*/
it should "create a declaration with a List of strings" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "string")))
val m = config.toDeclaration(property)
m._1 should be ("List[String]")
m._2 should be ("_")
}
/*
* support list declarations with int inner value and the correct default value
*/
it should "create a declaration with a List of ints" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "int")))
val m = config.toDeclaration(property)
m._1 should be ("List[Int]")
m._2 should be ("0")
}
/*
* support list declarations with float inner value and the correct default value
*/
it should "create a declaration with a List of floats" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "float")))
val m = config.toDeclaration(property)
m._1 should be ("List[Float]")
m._2 should be ("0f")
}
/*
* support list declarations with double inner value and the correct default value
*/
it should "create a declaration with a List of doubles" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "nothing",
items=Some(ModelRef(`type`= "double")))
val m = config.toDeclaration(property)
m._1 should be ("List[Double]")
m._2 should be ("0.0")
}
/*
* support list declarations with complex inner value and the correct default value
*/
it should "create a declaration with a List of complex objects" in {
val property = ModelProperty(
`type` = "Array",
qualifiedType = "Array",
items = Some(ModelRef(`type`= "User")))
val m = config.toDeclaration(property)
m._1 should be ("List[User]")
m._2 should be ("_")
}
it should "verify an api map with query params" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json", None)
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val codegen = new Codegen(config)
val petApi = apis.filter(doc => doc.resourcePath == "/pet").head
val endpoint = petApi.apis.filter(api => api.path == "/pet.{format}/findByTags").head
val operation = endpoint.operations.filter(op => op.method == "GET").head
val m = codegen.apiToMap("http://my.api.com/api", operation)
m("path") should be ("http://my.api.com/api")
m("bodyParams").asInstanceOf[List[_]].size should be (0)
m("httpMethod") should be ("GET")
// Pet => NIKPet
m("returnBaseType") should be (Some("Pet"))
m("returnType") should be (Some("List[Pet]"))
m("returnTypeIsPrimitive") should be (None)
m("pathParams").asInstanceOf[List[_]].size should be (0)
m("returnContainer") should be (Some("List"))
m("requiredParamCount") should be ("1")
val queryParams = m("queryParams").asInstanceOf[List[_]]
queryParams.size should be (1)
val queryParam = queryParams.head.asInstanceOf[HashMap[String, _]]
queryParam("type") should be ("query")
queryParam("dataType") should be ("String")
queryParam("required") should be ("true")
queryParam("paramName") should be ("tags")
queryParam("swaggerDataType") should be ("string")
queryParam("allowMultiple") should be ("true")
queryParam("defaultValue") should be (None)
}
it should "verify an api map with query params with default values" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json", None)
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val codegen = new Codegen(config)
val petApi = apis.filter(doc => doc.resourcePath == "/pet").head
val endpoint = petApi.apis.filter(api => api.path == "/pet.{format}/findByStatus").head
val operation = endpoint.operations.filter(op => op.method == "GET").head
val m = codegen.apiToMap("http://my.api.com/api", operation)
m("path") should be ("http://my.api.com/api")
m("bodyParams").asInstanceOf[List[_]].size should be (0)
m("httpMethod") should be ("GET")
// Pet => Pet
m("returnBaseType") should be (Some("Pet"))
// problem here
m("returnType") should be (Some("List[Pet]"))
m("returnTypeIsPrimitive") should be (None)
m("pathParams").asInstanceOf[List[_]].size should be (0)
m("returnContainer") should be (Some("List"))
m("requiredParamCount") should be ("1")
val queryParams = m("queryParams").asInstanceOf[List[_]]
queryParams.size should be (1)
val queryParam = queryParams.head.asInstanceOf[HashMap[String, _]]
queryParam("type") should be ("query")
queryParam("dataType") should be ("String")
queryParam("required") should be ("true")
queryParam("paramName") should be ("status")
queryParam("swaggerDataType") should be ("string")
queryParam("allowMultiple") should be ("true")
queryParam("defaultValue") should be (Some("\"available\""))
queryParam("allowableValues") should be (Some("LIST[available,pending,sold]"))
}
it should "create an api file" in {
implicit val basePath = "http://localhost:8080/api"
val codegen = new Codegen(config)
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json", None)
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val petApi = apis.filter(doc => doc.resourcePath == "/pet").head
val endpoint = petApi.apis.filter(api => api.path == "/pet.{format}/findByTags").head
val operation = endpoint.operations.filter(op => op.method == "GET").head
val m = codegen.apiToMap("http://my.api.com/api", operation)
val allModels = new HashMap[String, Model]
val operations = config.extractApiOperations(List(petApi), allModels)
val operationMap = config.groupOperationsToFiles(operations)
val apiBundle = config.prepareApiBundle(operationMap.toMap)
val apiInfo = config.writeFiles(apiBundle, config.apiTemplateFiles.toMap)
apiInfo.size should be (1)
val file = apiInfo.head
// verify the filename is set
// file._1.indexOf("""PetApi.scala""") should not be (-1)
// verify the default value for status exists
// file._2.indexOf("""(status: String= "available")""") should not be (-1)
}
}

View File

@ -1,135 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.util._
import com.wordnik.swagger.codegen.language._
import com.wordnik.swagger.codegen.PathUtil
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.beans.BeanProperty
@RunWith(classOf[JUnitRunner])
class CodegenConfigTest extends FlatSpec with Matchers {
class SampleCodegenConfig extends CodegenConfig with PathUtil {
override def packageName = "com.test"
override def templateDir = "src/test/resources/sampleConfigTemplates"
override def destinationDir = {
val tmpFile = java.io.File.createTempFile("test",".tmp")
tmpFile.delete; tmpFile.mkdir
tmpFile.deleteOnExit
tmpFile.toString
}
override def escapeReservedWord(word: String) = "`" + word + "`"
override def typeMapping = Map("int" -> "integer")
override def invokerPackage = Some("com.wordnik.something")
override def apiPackage: Option[String] = Some("com.wordnik.api")
override def modelPackage = Some("com.wordnik.models")
override def reservedWords = Set("special")
override def importMapping = super.importMapping ++ Map("User" -> "com.mypackage.User")
}
val config = new SampleCodegenConfig
behavior of "PathUtil"
/*
* We will take an api in the spec and create an API name from it
*/
it should "convert an api name" in {
config.toApiName("fun") should be ("FunApi")
}
/*
* We need to generate an API name from the resource path,
* i.e. /foo will follow rules to become FooApi
*/
it should "convert a path" in {
config.apiNameFromPath("/foo/bar/cats/dogs") should be ("FooApi")
}
behavior of "CodegenConfig"
/*
* A response of type "void" will turn into a declaration of None
* for the template generator
*/
it should "process a response declaration" in {
config.processResponseDeclaration("void") should be (None)
}
/*
* if a response declaration is valid as-is, it will be
* unchanged
*/
it should "process an unchanged response" in {
config.processResponseDeclaration("string") should be (Some("string"))
}
/*
* if a typeMapping is configured, the response type declaration
* from a method should be translated
*/
it should "process an mapped response type" in {
config.processResponseDeclaration("int") should be (Some("integer"))
}
/*
* returns the invoker package from the config
*/
it should "get the invoker package" in {
config.invokerPackage should be (Some("com.wordnik.something"))
}
/*
* returns the api package
*/
it should "get the api package" in {
config.apiPackage should be (Some("com.wordnik.api"))
}
/*
* returns the model package
*/
it should "get the model package" in {
config.modelPackage should be (Some("com.wordnik.models"))
}
/*
* types are mapped between swagger types and language-specific
* types
*/
it should "convert to a declared type" in {
config.toDeclaredType("int") should be ("integer")
}
/*
* codegen should honor special imports to avoid generating
* classes
*/
it should "honor the import mapping" in {
config.importMapping("User") should be ("com.mypackage.User")
}
/*
* reserved words should be treated appropriately by the config,
* either by quoting or manipulating them with a prefix/suffix
*/
it should "quote a reserved var name" in {
config.toVarName("special") should be ("`special`")
}
}

View File

@ -1,55 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.Codegen
import com.wordnik.swagger.codegen.BasicJavaGenerator
import com.wordnik.swagger.codegen.model._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.beans.BeanProperty
@RunWith(classOf[JUnitRunner])
class CodegenTest extends FlatSpec with Matchers {
val subject = new Codegen(new BasicJavaGenerator)
val testOp = new Operation("GET",
"List All Contacts",
"",
"Array[ContactData]",
"listContacts",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List.empty,
List.empty,
None)
behavior of "Codegen"
/*
* A return specified as "Array" should map to "List"
*/
it should "recognize the returnContainer as a List" in {
val map = subject.apiToMap("/contacts", testOp)
map("returnContainer") should be (Some("List"))
}
}

View File

@ -1,55 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.wordnik.swagger.codegen.BasicScalaGenerator
import com.wordnik.swagger.codegen.PathUtil
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
@RunWith(classOf[JUnitRunner])
class PathUtilTest extends FlatSpec with Matchers {
val config = new BasicScalaGenerator
behavior of "PathUtil"
/*
* We will take an api in the spec and create an API name from it
*/
it should "convert an api name" in {
config.toApiName("fun") should be ("FunApi")
}
/*
* We need to generate an API name from the resource path,
* i.e. /foo will follow rules to become FooApi
*/
it should "convert a path" in {
config.apiNameFromPath("/foo/bar/cats/dogs") should be ("FooApi")
}
/**
* since swagger-spec 1.2 doesn't support `basePath` in the Resource Listing,
* ensure the base path is extracted from the input host
**/
it should "get determine the basePath implicitly" in {
sys.props -= "fileMap"
new PathUtilImpl().getBasePath("http://foo.com/api-docs", "") should be ("http://foo.com/api-docs")
}
}
class PathUtilImpl extends PathUtil

View File

@ -1,267 +0,0 @@
package swaggerSpec1_1
import com.wordnik.swagger.codegen.util.CoreUtils
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.util._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.read
import scala.collection.mutable.LinkedHashMap
@RunWith(classOf[JUnitRunner])
class CoreUtilsTest extends FlatSpec with Matchers {
sys.props += "fileMap" -> "src/test/resources/petstore-1.1"
behavior of "CoreUtils"
it should "verify models are extracted" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json")
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val cu = CoreUtils.extractAllModels(apis)
cu.size should be (5)
(cu.keys.toSet & Set("User", "Tag", "Pet", "Category", "Order")).size should be (5)
}
it should "verify operation names" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json")
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val petApi = apis.filter(api => api.resourcePath == "/pet").head
val eps = petApi.apis.map(api => (api.path, api)).toMap
val ops = eps("/pet.{format}").operations.map(ep => (ep.nickname, ep)).toMap
ops.size should be (2)
(ops.keys.toSet & Set("addPet", "updatePet")).size should be (2)
}
it should "find required models" in {
val apis = CoreUtilsTest.sampleApis1
val models = CoreUtils.extractApiModels(apis.head)
models.size should be (5)
}
it should "find required models from a nested list" in {
val apis = CoreUtilsTest.sampleApis2
val models = CoreUtils.extractApiModels(apis.head)
models.size should be (5)
}
}
object CoreUtilsTest {
implicit val formats = SwaggerSerializers.formats("1.1")
def sampleApis1 = {
parse("""
[
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "http://api.helloreverb.com/api",
"resourcePath": "/mysteries",
"apis": [
{
"path": "/mysteries.{format}/{petId}",
"description": "As the name suggests",
"operations": [
{
"httpMethod": "GET",
"summary": "You find amazing htings here",
"responseClass": "DeepMystery",
"nickname": "getMysteryById",
"parameters": [
{
"name": "id",
"description": "ID of mystery",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"MysteryList": {
"id": "MysteryList",
"properties": {
"id": {
"type": "long"
},
"mysteries": {
"items":{
"$ref":"Mystery1"
},
"type":"Array"
}
}
},
"DeepMystery": {
"id": "DeepMystery",
"properties": {
"id": {
"type": "Mystery1"
},
"name": {
"type": "string"
}
}
},
"Mystery1": {
"id": "Mystery1",
"properties": {
"mystery2": {
"type": "Mystery2"
},
"name": {
"type": "string"
}
}
},
"Mystery2": {
"id": "Mystery2",
"properties": {
"mystery3": {
"type": "Mystery3"
},
"name": {
"type": "string"
}
}
},
"Mystery3": {
"id": "Mystery3",
"properties": {
"mystery4": {
"type": "Mystery4"
},
"name": {
"type": "string"
}
}
},
"Mystery4": {
"id": "Mystery4",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
]
""").extract[List[ApiListing]]
}
def sampleApis2 = {
parse("""
[
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "http://api.helloreverb.com/api",
"resourcePath": "/mysteries",
"apis": [
{
"path": "/mysteries.{format}/{petId}",
"description": "As the name suggests",
"operations": [
{
"httpMethod": "GET",
"summary": "You find amazing htings here",
"responseClass": "MysteryList",
"nickname": "getMysteryById",
"parameters": [
{
"name": "id",
"description": "ID of mystery",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"MysteryList": {
"id": "MysteryList",
"properties": {
"id": {
"type": "long"
},
"mystery1": {
"type":"Mystery1"
}
}
},
"Mystery1": {
"id": "Mystery1",
"properties": {
"mystery2": {
"type": "Mystery2"
},
"name": {
"type": "string"
}
}
},
"Mystery2": {
"id": "Mystery2",
"properties": {
"mystery3List": {
"items": {
"$ref": "Mystery3"
},
"type": "List"
},
"name": {
"type": "string"
}
}
},
"Mystery3": {
"id": "Mystery3",
"properties": {
"mystery4": {
"type": "Mystery4"
},
"name": {
"type": "string"
}
}
},
"Mystery4": {
"id": "Mystery4",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
]
""").extract[List[ApiListing]]
}
}

View File

@ -1,552 +0,0 @@
package swaggerSpec1_1
import com.wordnik.swagger.codegen.model._
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{read, write}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.mutable.{ LinkedHashMap, ListBuffer }
@RunWith(classOf[JUnitRunner])
class ResourceListingValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "fail resource listing without base path" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.1"
}
"""
val listing = parse(jsonString).extract[ResourceListing]
val errors = SwaggerValidator.validate(listing)
// errors.size should be (1)
}
it should "fail resource listing without apiVersion" in {
val jsonString = """
{
"basePath": "http://foo.com",
"swaggerVersion":"1.1"
}
"""
val listing = parse(jsonString).extract[ResourceListing]
val errors = SwaggerValidator.validate(listing)
errors.size should be (1)
}
it should "fail with missing paths in a ResourceListing" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.1",
"basePath":"http://foo/bar",
"apis":[
{
"description":"path ab apis"
},{
"path":"/c",
"description":"path c apis"
}
]
}
"""
parse(jsonString).extract[ResourceListing] match {
case e: ResourceListing => {
e.apis.size should be (2)
val errors = SwaggerValidator.validate(e)
errors.size should be (1)
}
case _ => fail("didn't parse the underlying apis")
}
}
}
@RunWith(classOf[JUnitRunner])
class ApiListingReferenceValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an ApiListingReference" in {
val jsonString = """
{
"description":"the description"
}
"""
parse(jsonString).extract[ApiListingReference] match {
case p: ApiListingReference => {
p.description should be (Some("the description"))
val errors = new ListBuffer[ValidationError]
SwaggerValidator.validate(p, errors, "")
errors.size should be (1)
}
case _ => fail("wrong type returned, should be ApiListingReference")
}
}
it should "serialize an ApiListingReference" in {
val l = ApiListingReference("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ApiDescriptionValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "fail to deserialize an ApiDescription with path, method, return type" in {
val jsonString = """
{
"description":"the description",
"operations":[
{
"summary":"the summary",
"notes":"the notes",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"dataType":"string",
"allowableValues":{
"valueType":"LIST",
"values":["a","b","c"]
},
"paramType":"query"
}
]
}
]
}
"""
parse(jsonString).extract[ApiDescription] match {
case p: ApiDescription => {
val errors = new ListBuffer[ValidationError]
SwaggerValidator.validate(p, errors, "")
errors.size should be (3)
}
case _ => fail("wrong type returned, should be ApiDescription")
}
}
}
@RunWith(classOf[JUnitRunner])
class OperationValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "fail to deserialize an Operation with missing param type" in {
val jsonString = """
{
"httpMethod":"GET",
"summary":"the summary",
"notes":"the notes",
"responseClass":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"dataType":"string",
"allowableValues":{
"valueType":"LIST",
"values":["a","b","c"]
}
}
]
}
"""
val json = parse(jsonString)
json.extract[Operation] match {
case op: Operation => {
val errors = new ListBuffer[ValidationError]
SwaggerValidator.validate(op, errors, "")
errors.size should be (1)
}
case _ => fail("wrong type returned, should be Operation")
}
}
it should "serialize an operation" in {
val op = Operation(
"get",
"the summary",
"the notes",
"string",
"getMeSomeStrings",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List(Parameter("id", Some("the id"), Some("-1"), false, true, "string", AllowableListValues(List("a","b","c")), "query"))
)
write(op) should be ("""{"method":"get","summary":"the summary","notes":"the notes","responseClass":"string","nickname":"getMeSomeStrings","parameters":[{"name":"id","description":"the id","defaultValue":"-1","required":false,"allowMultiple":true,"dataType":"string","allowableValues":{"valueType":"LIST","values":["a","b","c"]},"paramType":"query"}]}""")
}
}
@RunWith(classOf[JUnitRunner])
class ResponseMessageValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an ResponseMessage" in {
val jsonString = """
{
"code":101,
"reason":"the message"
}
"""
val json = parse(jsonString)
json.extract[ResponseMessage] match {
case p: ResponseMessage => {
p.code should be (101)
p.message should be ("the message")
}
case _ => fail("wrong type returned, should be ResponseMessage")
}
}
it should "serialize an operation" in {
val l = ResponseMessage(101, "the message")
write(l) should be ("""{"code":101,"message":"the message"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ParameterValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize another param" in {
val jsonString = """
{
"name":"includeDuplicates",
"defaultValue":"false",
"description":"Show duplicate examples from different sources",
"required":"false",
"allowableValues":{
"values":[
false,
true
],
"valueType":"LIST"
},
"dataType":"string",
"allowMultiple":false,
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("includeDuplicates")
p.description should be (Some("Show duplicate examples from different sources"))
p.defaultValue should be (Some("false"))
p.required should be (false)
p.allowMultiple should be (false)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "deserialize a parameter" in {
val jsonString = """
{
"name":"name",
"description":"description",
"defaultValue":"tony",
"required":false,
"allowMultiple":true,
"dataType":"string",
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("name")
p.description should be (Some("description"))
p.defaultValue should be (Some("tony"))
p.required should be (false)
p.allowMultiple should be (true)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "serialize a parameter" in {
val l = Parameter("name", Some("description"), Some("tony"), false, true, "string", AnyAllowableValues, "query")
write(l) should be ("""{"name":"name","description":"description","defaultValue":"tony","required":false,"allowMultiple":true,"dataType":"string","paramType":"query"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize a model" in {
val jsonString = """
{
"id":"Foo",
"name":"Bar",
"properties": {
"id": {
"type":"string",
"required":true,
"description":"id"
},
"name": {
"type":"string",
"required":false,
"description":"name"
},
"tags": {
"type":"Array",
"items": {
"type":"string"
}
}
},
"description":"nice model"
}
"""
val json = parse(jsonString)
json.extract[Model] match {
case model: Model => {
model.id should be ("Foo")
model.name should be ("Bar")
model.properties should not be (null)
model.properties.size should be (3)
model.description should be (Some("nice model"))
model.properties("id") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (true)
e.description should be (Some("id"))
}
case _ => fail("missing property id")
}
model.properties("name") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (false)
e.description should be (Some("name"))
}
case _ => fail("missing property name")
}
model.properties("tags") match {
case e: ModelProperty => {
e.`type` should be ("Array")
e.required should be (false)
e.items match {
case Some(items) => items.`type` should be ("string")
case _ => fail("didn't find ref for Array")
}
}
case _ => fail("missing property name")
}
}
case _ => fail("expected type Model")
}
}
it should "serialize a model" in {
val ref = Model("Foo", "Bar", "Bar", (LinkedHashMap("s" -> ModelProperty("string", "string", 0, true, Some("a string")))))
write(ref) should be ("""{"id":"Foo","name":"Bar","properties":{"s":{"type":"string","required":true,"description":"a string"}}}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelRefValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize a model ref" in {
val jsonString = """
{
"$ref":"Foo",
"type":"Bar"
}
"""
val json = parse(jsonString)
json.extract[ModelRef] match {
case p: ModelRef => {
p.ref should be (Some("Foo"))
p.`type` should be ("Bar")
}
case _ => fail("expected type ModelRef")
}
}
it should "serialize a model ref" in {
val ref = ModelRef("Foo", Some("Bar"))
write(ref) should be ("""{"type":"Foo","$ref":"Bar"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelPropertyValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize a model property with allowable values and ref" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"allowableValues": {
"valueType":"LIST",
"values":["1","2","3"]
},
"items":{
"type":"Foo",
"$ref":"Bar"
}
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
p.items match {
case Some(e: ModelRef) => {
e.`type` should be ("Foo")
e.ref should be (Some("Bar"))
}
case _ => fail("expected type ModelProperty")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values and ref" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")),Some(ModelRef("Foo",Some("Bar"))))
write(p) should be ("""{"type":"string","required":false,"description":"nice","allowableValues":{"valueType":"LIST","values":["a","b"]},"items":{"type":"Foo","$ref":"Bar"}}""")
}
it should "deserialize a model property with allowable values" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"allowableValues": {
"valueType":"LIST",
"values":["1","2","3"]
}
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")))
write(p) should be ("""{"type":"string","required":false,"description":"nice","allowableValues":{"valueType":"LIST","values":["a","b"]}}""")
}
it should "deserialize a model property" in {
val jsonString = """
{
"type":"string",
"required":true,
"description":"nice"
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (true)
p.description should be (Some("nice"))
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"))
write(p) should be ("""{"type":"string","required":false,"description":"nice"}""")
}
}
@RunWith(classOf[JUnitRunner])
class AllowableValuesValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize allowable value list" in {
val allowableValuesListString = """
{
"valueType":"LIST",
"values":["1","2","3"]
}
"""
val json = parse(allowableValuesListString)
json.extract[AllowableValues] match {
case avl: AllowableListValues => {
avl.valueType should be ("LIST")
avl.values should be (List("1","2","3"))
}
}
}
it should "serialize allowable values list" in {
val l = AllowableListValues(List("1","2","3"))
write(l) should be ("""{"valueType":"LIST","values":["1","2","3"]}""")
}
it should "deserialize allowable values range" in {
val allowableValuesRangeString = """
{
"valueType":"RANGE",
"min":"abc",
"max":3
}
"""
val json = parse(allowableValuesRangeString)
json.extract[AllowableValues] match {
case avr: AllowableRangeValues => {
avr.min should be ("abc")
avr.max should be ("3")
}
case _ => fail("wrong type returned, should be AllowabeValuesList")
}
}
it should "serialize allowable values range" in {
val l = AllowableRangeValues("-1", "3")
write(l) should be ("""{"valueType":"RANGE","min":"-1","max":"3"}""")
}
}

View File

@ -1,641 +0,0 @@
package swaggerSpec1_1
import com.wordnik.swagger.codegen.model._
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{read, write}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.mutable.LinkedHashMap
@RunWith(classOf[JUnitRunner])
class ResourceListingSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an ResourceListing with no apis" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.1",
"basePath":"http://foo/bar"
}
"""
val json = parse(jsonString)
json.extract[ResourceListing] match {
case p: ResourceListing => {
p.apiVersion should be ("1.2.3")
p.swaggerVersion should be ("1.1")
p.basePath should be ("http://foo/bar")
p.apis.size should be (0)
}
case _ => fail("wrong type returned, should be ResourceListing")
}
}
it should "serialize an ApiListingReference with no apis" in {
val l = ApiListingReference("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
it should "deserialize an ResourceListing" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.1",
"basePath":"http://foo/bar",
"apis":[
{
"path":"/a/b",
"description":"path ab apis"
},{
"path":"/c",
"description":"path c apis"
}
]
}
"""
val json = parse(jsonString)
json.extract[ResourceListing] match {
case p: ResourceListing => {
p.apiVersion should be ("1.2.3")
p.swaggerVersion should be ("1.1")
p.basePath should be ("http://foo/bar")
p.apis.size should be (2)
}
case _ => fail("wrong type returned, should be ResourceListing")
}
}
it should "serialize an ApiListingReference" in {
val l = ApiListingReference("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ApiListingReferenceSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an ApiListingReference" in {
val jsonString = """
{
"path":"/foo/bar",
"description":"the description"
}
"""
val json = parse(jsonString)
json.extract[ApiListingReference] match {
case p: ApiListingReference => {
p.path should be ("/foo/bar")
p.description should be (Some("the description"))
}
case _ => fail("wrong type returned, should be ApiListingReference")
}
}
it should "serialize an ApiListingReference" in {
val l = ApiListingReference("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ApiDescriptionSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an ApiDescription with no ops" in {
val jsonString = """
{
"path":"/foo/bar",
"description":"the description"
}
"""
val json = parse(jsonString)
json.extract[ApiDescription] match {
case p: ApiDescription => {
p.path should be ("/foo/bar")
p.description should be (Some("the description"))
p.operations.size should be (0)
}
case _ => fail("wrong type returned, should be ApiDescription")
}
}
it should "serialize an ApiDescription with no operations" in {
val l = ApiDescription("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
it should "deserialize an ApiDescription" in {
val jsonString = """
{
"path":"/foo/bar",
"description":"the description",
"operations":[
{
"method":"GET",
"summary":"the summary",
"notes":"the notes",
"responseClass":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"dataType":"string",
"allowableValues":{
"valueType":"LIST",
"values":["a","b","c"]
},
"paramType":"query"
}
]
}
]
}
"""
val json = parse(jsonString)
json.extract[ApiDescription] match {
case p: ApiDescription => {
p.path should be ("/foo/bar")
p.description should be (Some("the description"))
p.operations.size should be (1)
p.operations.foreach(op => {
op.method should be ("GET")
op.summary should be ("the summary")
op.notes should be ("the notes")
op.responseClass should be ("string")
op.nickname should be ("getMeSomeStrings")
op.parameters.size should be (1)
op.parameters.foreach(m => {
m.name should be ("id")
m.description should be (Some("the id"))
m.defaultValue should be (Some("-1"))
m.required should be (false)
m.allowMultiple should be (true)
m.dataType should be ("string")
m.paramType should be ("query")
})
})
}
case _ => fail("wrong type returned, should be ApiDescription")
}
}
it should "serialize an ApiDescription" in {
val l = ApiDescription(
"/foo/bar",
Some("the description"),
List(Operation(
"get",
"the summary",
"the notes",
"string",
"getMeSomeStrings",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List(Parameter("id", Some("the id"), Some("-1"), false, true, "string", AllowableListValues(List("a","b","c")), "query"))
))
)
write(l) should be ("""{"path":"/foo/bar","description":"the description","operations":[{"method":"get","summary":"the summary","notes":"the notes","responseClass":"string","nickname":"getMeSomeStrings","parameters":[{"name":"id","description":"the id","defaultValue":"-1","required":false,"allowMultiple":true,"dataType":"string","allowableValues":{"valueType":"LIST","values":["a","b","c"]},"paramType":"query"}]}]}""")
}
}
@RunWith(classOf[JUnitRunner])
class OperationSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an Operation" in {
val jsonString = """
{
"method":"GET",
"summary":"the summary",
"notes":"the notes",
"responseClass":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"dataType":"string",
"allowableValues":{
"valueType":"LIST",
"values":["a","b","c"]
},
"paramType":"query"
}
]
}
"""
val json = parse(jsonString)
json.extract[Operation] match {
case op: Operation => {
op.method should be ("GET")
op.summary should be ("the summary")
op.notes should be ("the notes")
op.responseClass should be ("string")
op.nickname should be ("getMeSomeStrings")
op.parameters.size should be (1)
op.parameters.foreach(m => {
m.name should be ("id")
m.description should be (Some("the id"))
m.defaultValue should be (Some("-1"))
m.required should be (false)
m.allowMultiple should be (true)
m.dataType should be ("string")
m.paramType should be ("query")
})
}
case _ => fail("wrong type returned, should be Operation")
}
}
it should "serialize an operation" in {
val op = Operation(
"get",
"the summary",
"the notes",
"string",
"getMeSomeStrings",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List(Parameter("id", Some("the id"), Some("-1"), false, true, "string", AllowableListValues(List("a","b","c")), "query"))
)
write(op) should be ("""{"method":"get","summary":"the summary","notes":"the notes","responseClass":"string","nickname":"getMeSomeStrings","parameters":[{"name":"id","description":"the id","defaultValue":"-1","required":false,"allowMultiple":true,"dataType":"string","allowableValues":{"valueType":"LIST","values":["a","b","c"]},"paramType":"query"}]}""")
}
}
@RunWith(classOf[JUnitRunner])
class ErrorResponseSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize an ResponseResponse" in {
val jsonString = """
{
"code":101,
"reason":"the reason"
}
"""
val json = parse(jsonString)
json.extract[ResponseMessage] match {
case p: ResponseMessage => {
p.code should be (101)
p.message should be ("the reason")
}
case _ => fail("wrong type returned, should be ResponseMessage")
}
}
it should "serialize an operation" in {
val l = ResponseMessage(101, "the message")
write(l) should be ("""{"code":101,"message":"the message"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ParameterSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize another param" in {
val jsonString = """
{
"name":"includeDuplicates",
"defaultValue":"false",
"description":"Show duplicate examples from different sources",
"required":"false",
"allowableValues":{
"values":[
false,
true
],
"valueType":"LIST"
},
"dataType":"string",
"allowMultiple":false,
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("includeDuplicates")
p.description should be (Some("Show duplicate examples from different sources"))
p.defaultValue should be (Some("false"))
p.required should be (false)
p.allowMultiple should be (false)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "deserialize a parameter" in {
val jsonString = """
{
"name":"name",
"description":"description",
"defaultValue":"tony",
"required":false,
"allowMultiple":true,
"dataType":"string",
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("name")
p.description should be (Some("description"))
p.defaultValue should be (Some("tony"))
p.required should be (false)
p.allowMultiple should be (true)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "serialize a parameter" in {
val l = Parameter("name", Some("description"), Some("tony"), false, true, "string", AnyAllowableValues, "query")
write(l) should be ("""{"name":"name","description":"description","defaultValue":"tony","required":false,"allowMultiple":true,"dataType":"string","paramType":"query"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelSerializationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize a model" in {
val jsonString = """
{
"id":"Foo",
"name":"Bar",
"properties": {
"id": {
"type":"string",
"required":true,
"description":"id"
},
"name": {
"type":"string",
"required":false,
"description":"name"
},
"tags": {
"type":"Array",
"items": {
"type":"string"
}
}
},
"description":"nice model"
}
"""
val json = parse(jsonString)
json.extract[Model] match {
case model: Model => {
model.id should be ("Foo")
model.name should be ("Bar")
model.properties should not be (null)
model.properties.size should be (3)
model.description should be (Some("nice model"))
model.properties("id") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (true)
e.description should be (Some("id"))
}
case _ => fail("missing property id")
}
model.properties("name") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (false)
e.description should be (Some("name"))
}
case _ => fail("missing property name")
}
model.properties("tags") match {
case e: ModelProperty => {
e.`type` should be ("Array")
e.required should be (false)
e.items match {
case Some(items) => items.`type` should be ("string")
case _ => fail("didn't find ref for Array")
}
}
case _ => fail("missing property name")
}
}
case _ => fail("expected type Model")
}
}
it should "serialize a model" in {
val ref = Model("Foo", "Bar", "Bar", (LinkedHashMap("s" -> ModelProperty("string", "string", 0, true, Some("a string")))))
write(ref) should be ("""{"id":"Foo","name":"Bar","properties":{"s":{"type":"string","required":true,"description":"a string"}}}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelRefSerializationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize a model ref" in {
val jsonString = """
{
"$ref":"Foo",
"type":"Bar"
}
"""
val json = parse(jsonString)
json.extract[ModelRef] match {
case p: ModelRef => {
p.ref should be (Some("Foo"))
p.`type` should be ("Bar")
}
case _ => fail("expected type ModelRef")
}
}
it should "serialize a model ref" in {
val ref = ModelRef("Foo", Some("Bar"))
write(ref) should be ("""{"type":"Foo","$ref":"Bar"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelPropertySerializationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize a model property with allowable values and ref" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"allowableValues": {
"valueType":"LIST",
"values":["1","2","3"]
},
"items":{
"type":"Foo",
"$ref":"Bar"
}
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
p.items match {
case Some(e: ModelRef) => {
e.`type` should be ("Foo")
e.ref should be (Some("Bar"))
}
case _ => fail("expected type ModelProperty")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values and ref" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")),Some(ModelRef("Foo",Some("Bar"))))
write(p) should be ("""{"type":"string","required":false,"description":"nice","allowableValues":{"valueType":"LIST","values":["a","b"]},"items":{"type":"Foo","$ref":"Bar"}}""")
}
it should "deserialize a model property with allowable values" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"allowableValues": {
"valueType":"LIST",
"values":["1","2","3"]
}
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")))
write(p) should be ("""{"type":"string","required":false,"description":"nice","allowableValues":{"valueType":"LIST","values":["a","b"]}}""")
}
it should "deserialize a model property" in {
val jsonString = """
{
"type":"string",
"required":true,
"description":"nice"
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (true)
p.description should be (Some("nice"))
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"))
write(p) should be ("""{"type":"string","required":false,"description":"nice"}""")
}
}
@RunWith(classOf[JUnitRunner])
class AllowableValuesSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
it should "deserialize allowable value list" in {
val allowableValuesListString = """
{
"valueType":"LIST",
"values":["1","2","3"]
}
"""
val json = parse(allowableValuesListString)
json.extract[AllowableValues] match {
case avl: AllowableListValues => {
avl.valueType should be ("LIST")
avl.values should be (List("1","2","3"))
}
}
}
it should "serialize allowable values list" in {
val l = AllowableListValues(List("1","2","3"))
write(l) should be ("""{"valueType":"LIST","values":["1","2","3"]}""")
}
it should "deserialize allowable values range" in {
val allowableValuesRangeString = """
{
"valueType":"RANGE",
"min":"abc",
"max":3
}
"""
val json = parse(allowableValuesRangeString)
json.extract[AllowableValues] match {
case avr: AllowableRangeValues => {
avr.min should be ("abc")
avr.max should be ("3")
}
case _ => fail("wrong type returned, should be AllowabeValuesList")
}
}
it should "serialize allowable values range" in {
val l = AllowableRangeValues("-1", "3")
write(l) should be ("""{"valueType":"RANGE","min":"-1","max":"3"}""")
}
}

View File

@ -1,171 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package swaggerSpec1_1
import com.wordnik.swagger.codegen.model._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.read
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.io._
@RunWith(classOf[JUnitRunner])
class SwaggerModelTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.1")
behavior of "Swagger Model"
it should "deserialize ResourceListing" in {
val json = Source.fromFile("src/test/resources/petstore-1.1/resources.json").mkString
val listing = parse(json).extract[ResourceListing]
listing.apiVersion should be ("0.2")
listing.swaggerVersion should be ("1.1")
listing.basePath should be ("http://petstore.swagger.wordnik.com/api")
listing.apis.size should be (3)
val apis = listing.apis.map(api => (api.path, api.description)).toMap
apis("/store.{format}") should be (Some("Operations about store"))
apis("/pet.{format}") should be (Some("Operations about pets"))
apis("/user.{format}") should be (Some("Operations about user"))
}
it should "deserialize ApiListing" in {
val json = Source.fromFile("src/test/resources/petstore-1.1/pet.json").mkString
val apiListing = parse(json).extract[ApiListing]
apiListing.apiVersion should be ("0.2")
apiListing.swaggerVersion should be ("1.1")
apiListing.basePath should be ("http://petstore.swagger.wordnik.com/api")
apiListing.resourcePath should be ("/pet")
apiListing.apis.size should be (4)
apiListing.models.isDefined should be (true)
apiListing.models.get.size should be (3)
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
val petBaseApi = apiMap("/pet.{format}/{petId}")
petBaseApi.description should be (Some("Operations about pets"))
petBaseApi.operations.size should be (1)
val getPetById = petBaseApi.operations.head
getPetById.method should be ("GET")
getPetById.summary should be ("Find pet by ID")
getPetById.notes should be ("Returns a pet based on ID")
getPetById.responseClass should be ("Pet")
getPetById.nickname should be ("getPetById")
getPetById.parameters.size should be (1)
val param = getPetById.parameters.head
param.name should be ("petId")
param.description should be (Some("ID of pet that needs to be fetched"))
param.paramType should be ("path")
param.required should be (true)
param.allowMultiple should be (false)
param.dataType should be ("string")
getPetById.responseMessages.size should be (2)
val errors = getPetById.responseMessages.map(response => (response.code, response.message)).toMap
errors(400) should be ("Invalid ID supplied")
errors(404) should be ("Pet not found")
}
it should "deserialize ApiListing with AllowableValues" in {
val json = Source.fromFile("src/test/resources/petstore-1.1/pet.json").mkString
val apiListing = parse(json).extract[ApiListing]
val apiMap = apiListing.apis.map(api => (api.path, api)).toMap
val petBaseApi = apiMap("/pet.{format}/findByStatus")
val findPetsByStatus = petBaseApi.operations.head
val param = findPetsByStatus.parameters.head
param.name should be ("status")
param.description should be (Some("Status values that need to be considered for filter"))
param.paramType should be ("query")
param.required should be (true)
param.allowMultiple should be (true)
param.dataType should be ("string")
param.allowableValues should not be (null)
param.allowableValues.isInstanceOf[AllowableListValues] should be (true)
val allowableValues = param.allowableValues.asInstanceOf[AllowableListValues]
allowableValues.valueType should be ("LIST")
allowableValues.values.size should be (3)
(allowableValues.values.toSet & Set("available", "pending", "sold")).size should be (3)
}
it should "maintain model property order when deserializing" in {
val json = Source.fromFile("src/test/resources/petstore-1.1/pet.json").mkString
val apiListing = parse(json).extract[ApiListing]
val modelsOpt = apiListing.models
modelsOpt.isDefined should be (true)
val models = modelsOpt.get
models.size should be (3)
val pet = models("Pet")
val petProperties = pet.properties.toList
petProperties.size should be (6)
petProperties(0)._1 should be ("tags")
petProperties(1)._1 should be ("id")
petProperties(2)._1 should be ("category")
petProperties(3)._1 should be ("status")
petProperties(4)._1 should be ("name")
petProperties(5)._1 should be ("photoUrls")
}
it should "deserialize models" in {
val json = Source.fromFile("src/test/resources/petstore-1.1/pet.json").mkString
val apiListing = parse(json).extract[ApiListing]
val modelsOpt = apiListing.models
modelsOpt.isDefined should be (true)
val models = modelsOpt.get
models.size should be (3)
val pet = models("Pet")
pet.id should be ("Pet")
pet.properties.size should be (6)
val properties = pet.properties
val tags = properties("tags")
tags.`type` should be ("Array")
tags.items should not be (None)
tags.items.get.ref should be (Some("Tag"))
val id = properties("id")
// id.`type` shoud be ("long")
val category = properties("category")
category.`type` should be ("Category")
val status = properties("status")
status.`type` should be ("string")
status.description should be (Some("pet status in the store"))
status.allowableValues should not be (null)
status.allowableValues.isInstanceOf[AllowableListValues] should be (true)
val allowableValues = status.allowableValues.asInstanceOf[AllowableListValues]
allowableValues.valueType should be ("LIST")
(allowableValues.values.toSet & Set("available", "pending", "sold")).size should be (3)
}
}

View File

@ -1,65 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package swaggerSpec1_1
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.util.{ResourceExtractor, ApiExtractor, CoreUtils}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.JavaConverters._
import scala.beans.BeanProperty
@RunWith(classOf[JUnitRunner])
class ResourceExtractorTest extends FlatSpec with Matchers {
behavior of "ResourceExtractor"
it should "get 3 apis from a resource listing" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json")
resourceListing should not be(null)
resourceListing.apis.size should be (3)
}
}
@RunWith(classOf[JUnitRunner])
class ApiExtractorTest extends FlatSpec with Matchers {
behavior of "ApiExtractor"
it should "verify the deserialization of the store api" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.1/resources.json")
val docs = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.1", resourceListing.apis)
val m = docs.map(t => (t.resourcePath, t)).toMap
val storeApi = m("/store")
storeApi should not be (null)
storeApi.apis.size should be (2)
val f = storeApi.apis.map(m => (m.path, m)).toMap
(f.keys.toSet & Set("/store.{format}/order/{orderId}","/store.{format}/order")).size should be (2)
val storeOps = f("/store.{format}/order/{orderId}")
val ops = storeOps.operations.map(o => (o.nickname, o)).toMap
val getOrderById = ops("getOrderById")
getOrderById should not be null
getOrderById.method should be ("GET")
getOrderById.parameters.size should be (1)
getOrderById.responseMessages.size should be (2)
}
}

View File

@ -1,267 +0,0 @@
package swaggerSpec1_2
import com.wordnik.swagger.codegen.util.CoreUtils
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.util._
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.read
import scala.collection.mutable.LinkedHashMap
@RunWith(classOf[JUnitRunner])
class CoreUtilsTest extends FlatSpec with Matchers {
sys.props += "fileMap" -> "src/test/resources/petstore-1.2"
behavior of "CoreUtils"
it should "verify models are extracted" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.2/api-docs")
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.2", resourceListing.apis)
val cu = CoreUtils.extractAllModels(apis)
cu.size should be (5)
(cu.keys.toSet & Set("User", "Tag", "Pet", "Category", "Order")).size should be (5)
}
it should "verify operation names" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.2/api-docs")
val apis = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.2", resourceListing.apis)
val petApi = apis.filter(api => api.resourcePath == "/pet").head
val eps = petApi.apis.map(api => (api.path, api)).toMap
val ops = eps("/pet").operations.map(ep => (ep.nickname, ep)).toMap
ops.size should be (2)
(ops.keys.toSet & Set("addPet", "updatePet")).size should be (2)
}
it should "find required models" in {
val apis = CoreUtilsTest.sampleApis1
val models = CoreUtils.extractApiModels(apis.head)
models.size should be (5)
}
it should "find required models from a nested list" in {
val apis = CoreUtilsTest.sampleApis2
val models = CoreUtils.extractApiModels(apis.head)
models.size should be (5)
}
}
object CoreUtilsTest {
implicit val formats = SwaggerSerializers.formats("1.1")
def sampleApis1 = {
parse("""
[
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "http://api.helloreverb.com/api",
"resourcePath": "/mysteries",
"apis": [
{
"path": "/mysteries.{format}/{petId}",
"description": "As the name suggests",
"operations": [
{
"httpMethod": "GET",
"summary": "You find amazing htings here",
"responseClass": "DeepMystery",
"nickname": "getMysteryById",
"parameters": [
{
"name": "id",
"description": "ID of mystery",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"MysteryList": {
"id": "MysteryList",
"properties": {
"id": {
"type": "long"
},
"mysteries": {
"items":{
"$ref":"Mystery1"
},
"type":"Array"
}
}
},
"DeepMystery": {
"id": "DeepMystery",
"properties": {
"id": {
"type": "Mystery1"
},
"name": {
"type": "string"
}
}
},
"Mystery1": {
"id": "Mystery1",
"properties": {
"mystery2": {
"type": "Mystery2"
},
"name": {
"type": "string"
}
}
},
"Mystery2": {
"id": "Mystery2",
"properties": {
"mystery3": {
"type": "Mystery3"
},
"name": {
"type": "string"
}
}
},
"Mystery3": {
"id": "Mystery3",
"properties": {
"mystery4": {
"type": "Mystery4"
},
"name": {
"type": "string"
}
}
},
"Mystery4": {
"id": "Mystery4",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
]
""").extract[List[ApiListing]]
}
def sampleApis2 = {
parse("""
[
{
"apiVersion": "0.2",
"swaggerVersion": "1.1",
"basePath": "http://api.helloreverb.com/api",
"resourcePath": "/mysteries",
"apis": [
{
"path": "/mysteries/{petId}",
"description": "As the name suggests",
"operations": [
{
"httpMethod": "GET",
"summary": "You find amazing htings here",
"responseClass": "MysteryList",
"nickname": "getMysteryById",
"parameters": [
{
"name": "id",
"description": "ID of mystery",
"paramType": "path",
"required": true,
"allowMultiple": false,
"dataType": "string"
}
]
}
]
}
],
"models": {
"MysteryList": {
"id": "MysteryList",
"properties": {
"id": {
"type": "long"
},
"mystery1": {
"type":"Mystery1"
}
}
},
"Mystery1": {
"id": "Mystery1",
"properties": {
"mystery2": {
"type": "Mystery2"
},
"name": {
"type": "string"
}
}
},
"Mystery2": {
"id": "Mystery2",
"properties": {
"mystery3List": {
"items": {
"$ref": "Mystery3"
},
"type": "List"
},
"name": {
"type": "string"
}
}
},
"Mystery3": {
"id": "Mystery3",
"properties": {
"mystery4": {
"type": "Mystery4"
},
"name": {
"type": "string"
}
}
},
"Mystery4": {
"id": "Mystery4",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
}
]
""").extract[List[ApiListing]]
}
}

View File

@ -1,542 +0,0 @@
package swaggerSpec1_2
import com.wordnik.swagger.codegen.model._
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{read, write}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.mutable.{ LinkedHashMap, ListBuffer }
@RunWith(classOf[JUnitRunner])
class ResourceListingValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "not have base path" in {
// SwaggerSerializers.validationMessages.clear
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.1"
}
"""
val listing = parse(jsonString).extract[ResourceListing]
val errors = SwaggerValidator.validate(listing)
errors.size should be (0)
}
it should "fail resource listing without apiVersion" in {
// SwaggerSerializers.validationMessages.clear
val jsonString = """
{
"basePath": "http://foo.com",
"swaggerVersion":"1.2"
}
"""
val listing = parse(jsonString).extract[ResourceListing]
val errors = SwaggerValidator.validate(listing)
errors.size should be (1)
}
it should "fail with missing paths in a ResourceListing" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.2",
"apis":[
{
"description":"path ab apis"
},
{
"path":"/c",
"description":"path c apis"
}
]
}
"""
parse(jsonString).extract[ResourceListing] match {
case e: ResourceListing => {
e.apis.size should be (1)
val errors = SwaggerValidator.validate(e)
errors.size should be (0)
}
case _ => fail("didn't parse the underlying apis")
}
}
}
@RunWith(classOf[JUnitRunner])
class ApiListingReferenceValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an ApiListingReference" in {
// SwaggerSerializers.validationMessages.clear
val jsonString = """
{
"description":"the description"
}
"""
parse(jsonString).extract[ApiListingReference] match {
case p: ApiListingReference => {
p.description should be (Some("the description"))
val errors = new ListBuffer[ValidationError]
SwaggerValidator.validate(p, errors, "")
errors.size should be (1)
}
case _ => fail("wrong type returned, should be ApiListingReference")
}
}
it should "serialize an ApiListingReference" in {
val l = ApiListingReference("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ApiDescriptionValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "fail to deserialize an ApiDescription with path, method, return type" in {
// SwaggerSerializers.validationMessages.clear
val jsonString = """
{
"description":"the description",
"operations":[
{
"summary":"the summary",
"notes":"the notes",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"type":"string",
"enum":["a","b","c"],
"paramType":"query"
}
]
}
]
}
"""
parse(jsonString).extract[ApiDescription] match {
case p: ApiDescription => {
val errors = new ListBuffer[ValidationError]
SwaggerValidator.validate(p, errors, "")
errors.size should be (3)
}
case _ => fail("wrong type returned, should be ApiDescription")
}
}
}
@RunWith(classOf[JUnitRunner])
class OperationValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "fail to deserialize an Operation with missing param type" in {
// SwaggerSerializers.validationMessages.clear
val jsonString = """
{
"httpMethod":"GET",
"summary":"the summary",
"notes":"the notes",
"type":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"type":"string",
"enum":["a","b","c"]
}
]
}
"""
val json = parse(jsonString)
json.extract[Operation] match {
case op: Operation => {
val errors = new ListBuffer[ValidationError]
SwaggerValidator.validate(op, errors, "")
errors.size should be (1)
}
case _ => fail("wrong type returned, should be Operation")
}
}
it should "serialize an operation" in {
val op = Operation(
"get",
"the summary",
"the notes",
"string",
"getMeSomeStrings",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List(Parameter("id", Some("the id"), Some("-1"), false, true, "string", AllowableListValues(List("a","b","c")), "query"))
)
write(op) should be ("""{"method":"get","summary":"the summary","notes":"the notes","type":"string","nickname":"getMeSomeStrings","parameters":[{"name":"id","description":"the id","defaultValue":"-1","required":false,"allowMultiple":true,"type":"string","paramType":"query","enum":["a","b","c"]}]}""")
}
}
@RunWith(classOf[JUnitRunner])
class ResponseMessageValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an ResponseMessage" in {
val jsonString = """
{
"code":101,
"message":"the message"
}
"""
val json = parse(jsonString)
json.extract[ResponseMessage] match {
case p: ResponseMessage => {
p.code should be (101)
p.message should be ("the message")
}
case _ => fail("wrong type returned, should be ResponseMessage")
}
}
it should "serialize an operation" in {
val l = ResponseMessage(101, "the message")
write(l) should be ("""{"code":101,"message":"the message"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ParameterValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize another param" in {
val jsonString = """
{
"name":"includeDuplicates",
"defaultValue":"false",
"description":"Show duplicate examples from different sources",
"required":"false",
"enum":[
false,
true
],
"type":"string",
"allowMultiple":false,
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("includeDuplicates")
p.description should be (Some("Show duplicate examples from different sources"))
p.defaultValue should be (Some("false"))
p.required should be (false)
p.allowMultiple should be (false)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "deserialize a parameter" in {
val jsonString = """
{
"name":"name",
"description":"description",
"defaultValue":"tony",
"required":false,
"allowMultiple":true,
"type":"string",
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("name")
p.description should be (Some("description"))
p.defaultValue should be (Some("tony"))
p.required should be (false)
p.allowMultiple should be (true)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "serialize a parameter" in {
val l = Parameter("name", Some("description"), Some("tony"), false, true, "string", AnyAllowableValues, "query")
write(l) should be ("""{"name":"name","description":"description","defaultValue":"tony","required":false,"allowMultiple":true,"type":"string","paramType":"query"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize a model" in {
val jsonString = """
{
"id":"Foo",
"name":"Bar",
"properties": {
"id": {
"type":"string",
"required":true,
"description":"id"
},
"name": {
"type":"string",
"required":false,
"description":"name"
},
"tags": {
"type":"Array",
"items": {
"type":"string"
}
}
},
"description":"nice model"
}
"""
val json = parse(jsonString)
json.extract[Model] match {
case model: Model => {
model.id should be ("Foo")
model.name should be ("Bar")
model.properties should not be (null)
model.properties.size should be (3)
model.description should be (Some("nice model"))
model.properties("id") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (true)
e.description should be (Some("id"))
}
case _ => fail("missing property id")
}
model.properties("name") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (false)
e.description should be (Some("name"))
}
case _ => fail("missing property name")
}
model.properties("tags") match {
case e: ModelProperty => {
e.`type` should be ("Array")
e.required should be (false)
e.items match {
case Some(items) => items.`type` should be ("string")
case _ => fail("didn't find ref for Array")
}
}
case _ => fail("missing property name")
}
}
case _ => fail("expected type Model")
}
}
it should "serialize a model" in {
val ref = Model("Foo", "Bar", "Bar", (LinkedHashMap("s" -> ModelProperty("string", "string", 0, true, Some("a string")))))
write(ref) should be ("""{"id":"Foo","name":"Bar","required":["s"],"properties":{"s":{"type":"string","description":"a string"}}}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelRefValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize a model ref" in {
val jsonString = """
{
"$ref":"Foo",
"type":"Bar"
}
"""
val json = parse(jsonString)
json.extract[ModelRef] match {
case p: ModelRef => {
p.ref should be (Some("Foo"))
p.`type` should be ("Bar")
}
case _ => fail("expected type ModelRef")
}
}
it should "serialize a model ref" in {
val ref = ModelRef("Foo", Some("Bar"))
write(ref) should be ("""{"type":"Foo","$ref":"Bar"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelPropertyValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize a model property with allowable values and ref" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"enum":["1","2","3"],
"items":{
"type":"Foo",
"$ref":"Bar"
}
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
p.items match {
case Some(e: ModelRef) => {
e.`type` should be ("Foo")
e.ref should be (Some("Bar"))
}
case _ => fail("expected type ModelProperty")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values and ref" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")),Some(ModelRef("Foo",Some("Bar"))))
write(p) should be ("""{"type":"string","description":"nice","items":{"type":"Foo","$ref":"Bar"},"enum":["a","b"]}""")
}
it should "deserialize a model property with allowable values" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"enum":["1","2","3"]
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")))
write(p) should be ("""{"type":"string","description":"nice","enum":["a","b"]}""")
}
it should "deserialize a model property" in {
val jsonString = """
{
"type":"string",
"required":true,
"description":"nice"
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (true)
p.description should be (Some("nice"))
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"))
write(p) should be ("""{"type":"string","description":"nice"}""")
}
}
@RunWith(classOf[JUnitRunner])
class AllowableValuesValidationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize allowable value list" in {
val allowableValuesListString = """
{
"valueType":"LIST",
"values":["1","2","3"]
}
"""
val json = parse(allowableValuesListString)
json.extract[AllowableValues] match {
case avl: AllowableListValues => {
avl.valueType should be ("LIST")
avl.values should be (List("1","2","3"))
}
}
}
it should "serialize allowable values list" in {
val l = AllowableListValues(List("1","2","3"))
write(l) should be ("""{"valueType":"LIST","values":["1","2","3"]}""")
}
it should "deserialize allowable values range" in {
val allowableValuesRangeString = """
{
"valueType":"RANGE",
"min":"abc",
"max":3
}
"""
val json = parse(allowableValuesRangeString)
json.extract[AllowableValues] match {
case avr: AllowableRangeValues => {
avr.min should be ("abc")
avr.max should be ("3")
}
case _ => fail("wrong type returned, should be AllowabeValuesList")
}
}
it should "serialize allowable values range" in {
val l = AllowableRangeValues("-1", "3")
write(l) should be ("""{"valueType":"RANGE","min":"-1","max":"3"}""")
}
}

View File

@ -1,877 +0,0 @@
package swaggerSpec1_2
import com.wordnik.swagger.codegen.model._
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
import org.json4s.jackson.Serialization.{read, write}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.mutable.LinkedHashMap
@RunWith(classOf[JUnitRunner])
class ResourceListingSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an ResourceListing with no apis" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.2"
}
"""
val json = parse(jsonString)
json.extract[ResourceListing] match {
case p: ResourceListing => {
p.apiVersion should be ("1.2.3")
p.swaggerVersion should be ("1.2")
p.apis.size should be (0)
p.authorizations.size should be (0)
}
case _ => fail("wrong type returned, should be ResourceListing")
}
}
it should "deserialize an ResourceListing" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.2",
"apis":[
{
"path":"/a/b",
"description":"path ab apis"
},{
"path":"/c",
"description":"path c apis"
}
],
"authorizations": {}
}
"""
val json = parse(jsonString)
json.extract[ResourceListing] match {
case p: ResourceListing => {
p.apiVersion should be ("1.2.3")
p.swaggerVersion should be ("1.2")
p.apis.size should be (2)
p.authorizations.size should be (0)
}
case _ => fail("wrong type returned, should be ResourceListing")
}
}
}
@RunWith(classOf[JUnitRunner])
class ApiListingReferenceSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an ApiListingReference" in {
val jsonString = """
{
"path":"/foo/bar",
"description":"the description"
}
"""
val json = parse(jsonString)
json.extract[ApiListingReference] match {
case p: ApiListingReference => {
p.path should be ("/foo/bar")
p.description should be (Some("the description"))
}
case _ => fail("wrong type returned, should be ApiListingReference")
}
}
it should "serialize an ApiListingReference" in {
val l = ApiListingReference("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ApiListingSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an ApiListing" in {
val jsonString = """
{
"apiVersion":"1.2.3",
"swaggerVersion":"1.2",
"basePath": "/foo/bar",
"resourcePath": "/a/b",
"produces": [ "application/json" ],
"authorizations": {},
"apis": []
}
"""
val json = parse(jsonString)
json.extract[ApiListing] match {
case p: ApiListing=> {
p.apiVersion should be ("1.2.3")
p.swaggerVersion should be ("1.2")
p.basePath should be ("/foo/bar")
p.resourcePath should be ("/a/b")
p.produces should be (List("application/json"))
p.authorizations.size should be (0)
p.models should be (None)
p.description should be (None)
p.position should be (0)
}
case _ => fail("wrong type returned, should be ApiListing")
}
}
it should "serialize an ApiListing" in {
val l = ApiListing(
apiVersion = "1.2.3",
swaggerVersion = "1.2",
basePath = "/foo/bar",
resourcePath = "/a/b"
)
write(l) should be ("""{"apiVersion":"1.2.3","resourcePath":"/a/b","swaggerVersion":"1.2","basePath":"/foo/bar"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ApiDescriptionSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an ApiDescription with no ops" in {
val jsonString = """
{
"path":"/foo/bar",
"description":"the description"
}
"""
val json = parse(jsonString)
json.extract[ApiDescription] match {
case p: ApiDescription => {
p.path should be ("/foo/bar")
p.description should be (Some("the description"))
p.operations.size should be (0)
}
case _ => fail("wrong type returned, should be ApiDescription")
}
}
it should "serialize an ApiDescription with no operations" in {
val l = ApiDescription("/foo/bar", Some("the description"))
write(l) should be ("""{"path":"/foo/bar","description":"the description"}""")
}
it should "deserialize an ApiDescription" in {
val jsonString = """
{
"path":"/foo/bar",
"description":"the description",
"operations":[
{
"method":"GET",
"summary":"the summary",
"notes":"the notes",
"type":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"type":"string",
"enum":["a","b","c"],
"paramType":"query"
}
],
"authorizations":{}
}
]
}
"""
val json = parse(jsonString)
json.extract[ApiDescription] match {
case p: ApiDescription => {
p.path should be ("/foo/bar")
p.description should be (Some("the description"))
p.operations.size should be (1)
p.operations.foreach(op => {
op.method should be ("GET")
op.summary should be ("the summary")
op.notes should be ("the notes")
op.responseClass should be ("string")
op.nickname should be ("getMeSomeStrings")
op.parameters.size should be (1)
op.parameters.foreach(m => {
m.name should be ("id")
m.description should be (Some("the id"))
m.defaultValue should be (Some("-1"))
m.required should be (false)
m.allowMultiple should be (true)
m.dataType should be ("string")
m.paramType should be ("query")
})
op.authorizations.size should be (0)
})
}
case _ => fail("wrong type returned, should be ApiDescription")
}
}
it should "serialize an ApiDescription" in {
val l = ApiDescription(
"/foo/bar",
Some("the description"),
List(Operation(
"get",
"the summary",
"the notes",
"string",
"getMeSomeStrings",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List(Parameter("id", Some("the id"), Some("-1"), false, true, "string", AllowableListValues(List("a","b","c")), "query"))
))
)
write(l) should be ("""{"path":"/foo/bar","description":"the description","operations":[{"method":"get","summary":"the summary","notes":"the notes","type":"string","nickname":"getMeSomeStrings","parameters":[{"name":"id","description":"the id","defaultValue":"-1","required":false,"allowMultiple":true,"type":"string","paramType":"query","enum":["a","b","c"]}]}]}""")
}
}
@RunWith(classOf[JUnitRunner])
class OperationSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an Operation" in {
val jsonString = """
{
"method":"GET",
"summary":"the summary",
"notes":"the notes",
"type":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"type":"string",
"enum":["a","b","c"],
"paramType":"query"
}
],
"authorizations":{}
}
"""
val json = parse(jsonString)
json.extract[Operation] match {
case op: Operation => {
op.method should be ("GET")
op.summary should be ("the summary")
op.notes should be ("the notes")
op.responseClass should be ("string")
op.nickname should be ("getMeSomeStrings")
op.parameters.size should be (1)
op.parameters.foreach(m => {
m.name should be ("id")
m.description should be (Some("the id"))
m.defaultValue should be (Some("-1"))
m.required should be (false)
m.allowMultiple should be (true)
m.dataType should be ("string")
m.paramType should be ("query")
})
op.authorizations.size should be (0)
}
case _ => fail("wrong type returned, should be Operation")
}
}
it should "deserialize an Operation with an array property" in {
val jsonString = """
{
"method":"GET",
"summary":"the summary",
"notes":"the notes",
"type":"string",
"nickname":"getMeSomePets",
"parameters":[
{
"name":"id",
"description":"the id",
"defaultValue":"-1",
"required":false,
"allowMultiple":true,
"type":"array",
"items": {
"$ref": "Pet"
},
"enum":["a","b","c"],
"paramType":"query"
}
]
}
"""
val json = parse(jsonString)
json.extract[Operation] match {
case op: Operation => {
op.method should be ("GET")
op.summary should be ("the summary")
op.notes should be ("the notes")
op.responseClass should be ("string")
op.nickname should be ("getMeSomePets")
op.parameters.size should be (1)
op.parameters.foreach(m => {
m.name should be ("id")
m.description should be (Some("the id"))
m.defaultValue should be (Some("-1"))
m.required should be (false)
m.allowMultiple should be (true)
m.dataType should be ("Array[Pet]")
m.paramType should be ("query")
})
}
case _ => fail("wrong type returned, should be Operation")
}
}
it should "serialize an operation" in {
val op = Operation(
"get",
"the summary",
"the notes",
"string",
"getMeSomeStrings",
0,
List.empty,
List.empty,
List.empty,
List.empty,
List(Parameter("id", Some("the id"), Some("-1"), false, true, "string", AllowableListValues(List("a","b","c")), "query"))
)
write(op) should be ("""{"method":"get","summary":"the summary","notes":"the notes","type":"string","nickname":"getMeSomeStrings","parameters":[{"name":"id","description":"the id","defaultValue":"-1","required":false,"allowMultiple":true,"type":"string","paramType":"query","enum":["a","b","c"]}]}""")
}
it should "deserialize an Operation with array" in {
val jsonString = """
{
"method":"GET",
"summary":"the summary",
"notes":"the notes",
"type":"string",
"nickname":"getMeSomeStrings",
"parameters":[
{
"name":"userId",
"description":"the id",
"defaultValue":"-1",
"required":false,
"type":"array",
"items": {
"format": "int64",
"type": "integer"
},
"paramType":"query"
}
]
}
"""
val json = parse(jsonString)
json.extract[Operation] match {
case op: Operation => {
op.method should be ("GET")
op.summary should be ("the summary")
op.notes should be ("the notes")
op.responseClass should be ("string")
op.nickname should be ("getMeSomeStrings")
op.parameters.size should be (1)
op.parameters.foreach(m => {
m.name should be ("userId")
m.description should be (Some("the id"))
m.defaultValue should be (Some("-1"))
m.required should be (false)
m.dataType should be ("Array[long]")
})
}
case _ => fail("wrong type returned, should be Operation")
}
}
}
@RunWith(classOf[JUnitRunner])
class ErrorResponseSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize an Response" in {
val jsonString = """
{
"code":101,
"message":"the message"
}
"""
val json = parse(jsonString)
json.extract[ResponseMessage] match {
case p: ResponseMessage => {
p.code should be (101)
p.message should be ("the message")
}
case _ => fail("wrong type returned, should be ResponseMessage")
}
}
it should "serialize an operation" in {
val l = ResponseMessage(101, "the message")
write(l) should be ("""{"code":101,"message":"the message"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ParameterSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize another param" in {
val jsonString = """
{
"name":"includeDuplicates",
"defaultValue":"false",
"description":"Show duplicate examples from different sources",
"required":"false",
"enum":[
false,
true
],
"type":"string",
"allowMultiple":false,
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("includeDuplicates")
p.description should be (Some("Show duplicate examples from different sources"))
p.defaultValue should be (Some("false"))
p.required should be (false)
p.allowMultiple should be (false)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "deserialize a parameter" in {
val jsonString = """
{
"name":"name",
"description":"description",
"defaultValue":"tony",
"required":false,
"allowMultiple":true,
"type":"string",
"paramType":"query"
}
"""
val json = parse(jsonString)
json.extract[Parameter] match {
case p: Parameter => {
p.name should be ("name")
p.description should be (Some("description"))
p.defaultValue should be (Some("tony"))
p.required should be (false)
p.allowMultiple should be (true)
p.dataType should be ("string")
p.paramType should be ("query")
}
case _ => fail("wrong type returned, should be Parameter")
}
}
it should "serialize a parameter" in {
val l = Parameter("name", Some("description"), Some("tony"), false, true, "string", AnyAllowableValues, "query")
write(l) should be ("""{"name":"name","description":"description","defaultValue":"tony","required":false,"allowMultiple":true,"type":"string","paramType":"query"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelSerializationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize a model" in {
val jsonString = """
{
"id":"Foo",
"name":"Bar",
"required": ["id"],
"properties": {
"id": {
"type":"string",
"description":"id"
},
"name": {
"type":"string",
"description":"name"
},
"tags": {
"type":"array",
"items": {
"type":"string"
}
}
},
"description":"nice model"
}
"""
val json = parse(jsonString)
json.extract[Model] match {
case model: Model => {
model.id should be ("Foo")
model.name should be ("Bar")
model.properties should not be (null)
model.properties.size should be (3)
model.description should be (Some("nice model"))
model.properties("id") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (true)
e.description should be (Some("id"))
}
case _ => fail("missing property id")
}
model.properties("name") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (false)
e.description should be (Some("name"))
}
case _ => fail("missing property name")
}
model.properties("tags") match {
case e: ModelProperty => {
e.`type` should be ("Array")
e.required should be (false)
e.items match {
case Some(items) => items.`type` should be ("string")
case _ => fail("didn't find ref for Array")
}
}
case _ => fail("missing property name")
}
}
case _ => fail("expected type Model")
}
}
it should "deserialize a model with a set" in {
val jsonString = """
{
"id":"Foo",
"name":"Bar",
"required": ["id"],
"properties": {
"id": {
"type":"string",
"description":"id"
},
"name": {
"type":"string",
"description":"name"
},
"tags": {
"type":"array",
"uniqueItems": true,
"items": {
"type":"string"
}
}
},
"description":"nice model"
}
"""
val json = parse(jsonString)
json.extract[Model] match {
case model: Model => {
model.id should be ("Foo")
model.name should be ("Bar")
model.properties should not be (null)
model.properties.size should be (3)
model.description should be (Some("nice model"))
model.properties("id") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (true)
e.description should be (Some("id"))
}
case _ => fail("missing property id")
}
model.properties("name") match {
case e: ModelProperty => {
e.`type` should be ("string")
e.required should be (false)
e.description should be (Some("name"))
}
case _ => fail("missing property name")
}
model.properties("tags") match {
case e: ModelProperty => {
e.`type` should be ("Set")
e.required should be (false)
e.items match {
case Some(items) => items.`type` should be ("string")
case _ => fail("didn't find ref for Array")
}
}
case _ => fail("missing property name")
}
}
case _ => fail("expected type Model")
}
}
it should "serialize a model" in {
val ref = Model("Foo", "Bar", "Bar", (LinkedHashMap("s" -> ModelProperty("string", "string", 0, true, Some("a string")))))
write(ref) should be ("""{"id":"Foo","name":"Bar","required":["s"],"properties":{"s":{"type":"string","description":"a string"}}}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelRefSerializationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize a model ref" in {
val jsonString = """
{
"$ref":"Foo",
"type":"Bar"
}
"""
val json = parse(jsonString)
json.extract[ModelRef] match {
case p: ModelRef => {
p.ref should be (Some("Foo"))
p.`type` should be ("Bar")
}
case _ => fail("expected type ModelRef")
}
}
it should "serialize a model ref" in {
val ref = ModelRef("Foo", Some("Bar"))
write(ref) should be ("""{"type":"Foo","$ref":"Bar"}""")
}
}
@RunWith(classOf[JUnitRunner])
class ModelPropertySerializationTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize a model property with allowable values and ref" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"enum":["1","2","3"],
"items":{
"type":"Foo",
"$ref":"Bar"
}
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
p.items match {
case Some(e: ModelRef) => {
e.`type` should be ("Foo")
e.ref should be (Some("Bar"))
}
case _ => fail("expected type ModelProperty")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values and ref" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")),Some(ModelRef("Foo",Some("Bar"))))
write(p) should be ("""{"type":"string","description":"nice","items":{"type":"Foo","$ref":"Bar"},"enum":["a","b"]}""")
}
it should "deserialize a model property with allowable values" in {
val jsonString = """
{
"type":"string",
"required":false,
"description":"nice",
"enum":["1","2","3"]
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (false)
p.description should be (Some("nice"))
p.allowableValues match {
case e: AllowableListValues => e.values should be (List("1","2","3"))
case _ => fail("expected allowable values")
}
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property with allowable values" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"), AllowableListValues(List("a","b")))
write(p) should be ("""{"type":"string","description":"nice","enum":["a","b"]}""")
}
it should "deserialize a model property" in {
val jsonString = """
{
"type":"string",
"required":true,
"description":"nice"
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("string")
p.required should be (true)
p.description should be (Some("nice"))
}
case _ => fail("expected type ModelProperty")
}
}
it should "serialize a model property" in {
val p = ModelProperty("string", "string", 0, false, Some("nice"))
write(p) should be ("""{"type":"string","description":"nice"}""")
}
it should "extract model properties" in {
val jsonString = """
{
"type":"integer",
"format":"int64",
"required":true,
"description":"nice"
}
"""
val json = parse(jsonString)
json.extract[ModelProperty] match {
case p: ModelProperty => {
p.`type` should be ("long")
p.required should be (true)
p.description should be (Some("nice"))
}
case _ => fail("expected type ModelProperty")
}
}
it should "extract model properties with arrays" in {
val jsonString = """
{
"id": "DocIdList",
"name": "DocIdList",
"properties": {
"docIds": {
"items": {
"format": "int64",
"type": "integer"
},
"type": "array"
}
}
}
"""
val json = parse(jsonString)
json.extract[Model] match {
case p: Model => {
p.properties should not be (null)
p.properties.size should be (1)
p.properties.keys.size should be (1)
for(key <- p.properties.keys) {
val property = p.properties(key)
property.`type` should be ("Array")
property.items should not be (None)
property.items.get.`type` should be ("long")
}
}
case _ => fail("expected type ModelProperty")
}
}
}
@RunWith(classOf[JUnitRunner])
class AllowableValuesSerializersTest extends FlatSpec with Matchers {
implicit val formats = SwaggerSerializers.formats("1.2")
it should "deserialize allowable value list" in {
val allowableValuesListString = """
{
"valueType":"LIST",
"values":["1","2","3"]
}
"""
val json = parse(allowableValuesListString)
json.extract[AllowableValues] match {
case avl: AllowableListValues => {
avl.valueType should be ("LIST")
avl.values should be (List("1","2","3"))
}
}
}
it should "serialize allowable values list" in {
val l = AllowableListValues(List("1","2","3"))
write(l) should be ("""{"valueType":"LIST","values":["1","2","3"]}""")
}
it should "deserialize allowable values range" in {
val allowableValuesRangeString = """
{
"valueType":"RANGE",
"min":"abc",
"max":3
}
"""
val json = parse(allowableValuesRangeString)
json.extract[AllowableValues] match {
case avr: AllowableRangeValues => {
avr.min should be ("abc")
avr.max should be ("3")
}
case _ => fail("wrong type returned, should be AllowabeValuesList")
}
}
it should "serialize allowable values range" in {
val l = AllowableRangeValues("-1", "3")
write(l) should be ("""{"valueType":"RANGE","min":"-1","max":"3"}""")
}
}

View File

@ -1,65 +0,0 @@
/**
* Copyright 2014 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package swaggerSpec1_2
import com.wordnik.swagger.codegen.model._
import com.wordnik.swagger.codegen.util.{ResourceExtractor, ApiExtractor, CoreUtils}
import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import scala.collection.JavaConverters._
import scala.beans.BeanProperty
@RunWith(classOf[JUnitRunner])
class ResourceExtractorTest extends FlatSpec with Matchers {
behavior of "ResourceExtractor"
it should "get 3 apis from a resource listing" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.2/api-docs")
resourceListing should not be(null)
resourceListing.apis.size should be (3)
}
}
@RunWith(classOf[JUnitRunner])
class ApiExtractorTest extends FlatSpec with Matchers {
behavior of "ApiExtractor"
it should "verify the deserialization of the store api" in {
val resourceListing = ResourceExtractor.fetchListing("src/test/resources/petstore-1.2/api-docs")
val docs = ApiExtractor.extractApiOperations(resourceListing.swaggerVersion, "src/test/resources/petstore-1.2", resourceListing.apis)
val m = docs.map(t => (t.resourcePath, t)).toMap
val storeApi = m("/store")
storeApi should not be (null)
storeApi.apis.size should be (2)
val f = storeApi.apis.map(m => (m.path, m)).toMap
(f.keys.toSet & Set("/store/order/{orderId}","/store/order")).size should be (2)
val storeOps = f("/store/order/{orderId}")
val ops = storeOps.operations.map(o => (o.nickname, o)).toMap
val getOrderById = ops("getOrderById")
getOrderById should not be null
getOrderById.method should be ("GET")
getOrderById.parameters.size should be (1)
getOrderById.responseMessages.size should be (2)
}
}