diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000000..9f93e067e8e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,11 @@
+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.
diff --git a/README.md b/README.md
index 3934c3df196..f1dcbc5514c 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,15 @@
## Overview
This is the swagger codegen project, which allows generation of client libraries automatically from a
-Swagger-compliant server. You can find out more about both the spec and the framework at
-http://swagger.wordnik.com. For more information about Wordnik's APIs, please visit http://developer.wordnik.com.
+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:
@@ -224,7 +231,7 @@ either repackage the library OR modify your codegen script to use a file path!
License
-------
-Copyright 2013 Wordnik, Inc.
+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.
diff --git a/bin/runscala.sh b/bin/runscala.sh
index 44090ab0632..d53e746366a 100755
--- a/bin/runscala.sh
+++ b/bin/runscala.sh
@@ -1,7 +1,6 @@
#!/bin/sh
SCRIPT="$0"
-SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
while [ -h "$SCRIPT" ] ; do
ls=`ls -ld "$SCRIPT"`
@@ -19,6 +18,7 @@ if [ ! -d "${APP_DIR}" ]; then
fi
cd $APP_DIR
+SCALA_RUNNER_VERSION=$(scala ./bin/Version.scala)
# if you've executed sbt assembly previously it will use that instead.
@@ -26,7 +26,7 @@ export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/
ags="$@"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/swagger-codegen.jar ]; then
- scala -cp target/scala-$SCALA_RUNNER_VERSION/swagger-codegen.jar $ags
+ scala -cp $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/swagger-codegen.jar $ags
else
echo "Please set scalaVersion := \"$SCALA_RUNNER_VERSION\" in build.sbt and run ./sbt assembly"
fi
diff --git a/bin/static-docs.sh b/bin/static-docs.sh
index 5884a3479b3..963d4734ca3 100755
--- a/bin/static-docs.sh
+++ b/bin/static-docs.sh
@@ -22,8 +22,8 @@ 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"
-ags="$@ SwaggerDocGenerator http://developer.wordnik.com/v4/resources.json"
+export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties -DfileMap=samples/client/wordnik-api/spec-files/resources.json"
+ags="$@ SwaggerDocGenerator https://api.wordnik.com/v4/resources.json"
if [ -f $APP_DIR/target/scala-$SCALA_RUNNER_VERSION/swagger-codegen.jar ]; then
scala -cp target/scala-$SCALA_RUNNER_VERSION/swagger-codegen.jar $ags
diff --git a/src/main/resources/scala/pom.mustache b/src/main/resources/scala/pom.mustache
index 8d6a86ee87c..4cb2c261fad 100644
--- a/src/main/resources/scala/pom.mustache
+++ b/src/main/resources/scala/pom.mustache
@@ -170,13 +170,13 @@
com.wordnik
- swagger-core_2.9.1
+ swagger-core_${scala-short-version}
${swagger-core-version}
compile
org.scalatest
- scalatest_2.9.1
+ scalatest_${scala-short-version}
${scala-test-version}
test
@@ -187,15 +187,34 @@
test
+
+
+ scala_2.10
+
+ 2.10.3
+ 2.10
+ 1.3.2
+ 2.1.2
+
+
+
+ scala_2.9.1
+
+ true
+
+
+ 2.9.1-1
+ 2.9.1
+ 1.1.0
+ 1.6.1
+
+
+
1.7
- 1.1.0
- 2.9.1-1
4.8.1
1.0.0
- 1.6.1
4.8.1
- 1.6.1
3.1.5
diff --git a/src/main/scala/com/wordnik/swagger/codegen/BasicAndroidJavaClient.scala b/src/main/scala/com/wordnik/swagger/codegen/BasicAndroidJavaClient.scala
index 46fa1eed6f4..111e0b7d896 100644
--- a/src/main/scala/com/wordnik/swagger/codegen/BasicAndroidJavaClient.scala
+++ b/src/main/scala/com/wordnik/swagger/codegen/BasicAndroidJavaClient.scala
@@ -72,7 +72,7 @@ class BasicAndroidJavaGenerator extends BasicJavaGenerator {
("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"),
+ ("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")
)
-}
\ No newline at end of file
+}
diff --git a/src/main/scala/com/wordnik/swagger/codegen/BasicGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/BasicGenerator.scala
index bd660d99721..87f19065390 100644
--- a/src/main/scala/com/wordnik/swagger/codegen/BasicGenerator.scala
+++ b/src/main/scala/com/wordnik/swagger/codegen/BasicGenerator.scala
@@ -43,12 +43,12 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
var codegen = new Codegen(this)
- def generateClient(args: Array[String]) = {
+ def generateClient(args: Array[String]): Unit = {
generateClientWithoutExit(args)
System.exit(0)
}
- def generateClientWithoutExit(args: Array[String]) {
+ 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/")
}
diff --git a/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala b/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala
index eec0ecd1710..3aa72cbe975 100644
--- a/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala
+++ b/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala
@@ -81,12 +81,12 @@ class Codegen(config: CodegenConfig) {
lb
})
opList += apiToMap(apiPath, operation)
-
+
CoreUtils.extractModelNames(operation).foreach(i => allImports += i)
}
})
}
-
+
case None =>
}
@@ -223,14 +223,14 @@ class Codegen(config: CodegenConfig) {
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 => {
+ operation.responseMessages.foreach(param => {
val params = new HashMap[String, AnyRef]
params += "code" -> param.code.toString()
params += "reason" -> param.message
params += "hasMore" -> "true"
- errorList += params
+ errorList += params
})
}
@@ -509,7 +509,7 @@ class Codegen(config: CodegenConfig) {
"defaultValue" -> config.toDeclaration(propertyDocSchema)._2,
"description" -> propertyDocSchema.description,
"notes" -> propertyDocSchema.description,
- "allowableValues" -> rawAllowableValuesToString(propertyDocSchema.allowableValues),
+ "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),
@@ -555,87 +555,110 @@ class Codegen(config: CodegenConfig) {
write(m)
}
- def writeSupportingClasses(apis: Map[(String, String), List[(String, Operation)]], models: Map[String, Model], apiVersion: String) = {
- val rootDir = new java.io.File(".")
- val engine = new TemplateEngine(Some(rootDir))
+ final def writeSupportingClasses(
+ apis: Map[(String, String), List[(String, Operation)]],
+ models: Map[String, Model],
+ apiVersion: String,
+ rootDir: Option[File],
+ dataF: (Map[(String, String), List[(String, Operation)]], Map[String, Model]) => Map[String, AnyRef]): Seq[File] = {
- val apiList = new ListBuffer[Map[String, AnyRef]]
- apis.foreach(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
- })
- })
+ val engine = new TemplateEngine(rootDir orElse Some(new File(".")))
+ val data = dataF(apis, models)
- val modelList = new ListBuffer[HashMap[String, AnyRef]]
-
- models.foreach(m => {
- val json = writeJson(m._2)
- modelList += HashMap(
- "modelName" -> m._1,
- "model" -> modelToMap(m._1, m._2),
- "filename" -> config.toModelFilename(m._1),
- "modelJson" -> json,
- "hasMoreModels" -> "true")
- })
- modelList.size match {
- case 0 =>
- case _ => modelList.last.asInstanceOf[HashMap[String, String]] -= "hasMoreModels"
- }
-
- val data: HashMap[String, AnyRef] =
- HashMap(
- "invokerPackage" -> config.invokerPackage,
- "package" -> config.packageName,
- "modelPackage" -> config.modelPackage,
- "apiPackage" -> config.apiPackage,
- "apis" -> apiList,
- "models" -> modelList,
- "apiVersion" -> apiVersion) ++ config.additionalParams
-
- config.supportingFiles.map(file => {
+ val outputFiles = config.supportingFiles map { file =>
val supportingFile = file._1
val outputDir = file._2
val destFile = file._3
- val outputFilename = outputDir + File.separator + destFile
- val outputFolder = new File(outputFilename).getParent
+ val outputFile = new File(outputDir.replaceAll("\\.", File.separator) + File.separator + destFile)
+ val outputFolder = outputFile.getParent
new File(outputFolder).mkdirs
if (supportingFile.endsWith(".mustache")) {
val output = {
- val (resourceName, (_, template)) = compileTemplate(supportingFile, Some(rootDir), Some(engine))
+ val (resourceName, (_, template)) = compileTemplate(supportingFile, rootDir, Some(engine))
engine.layout(resourceName, template, data.toMap)
}
- val fw = new FileWriter(outputFilename, false)
+ val fw = new FileWriter(outputFile, false)
fw.write(output + "\n")
fw.close()
- println("wrote " + outputFilename)
+ println("wrote " + outputFile.getPath())
} else {
val file = new File(config.templateDir + File.separator + supportingFile)
- if(file.isDirectory()) {
+ 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 outputFile = new File(outputFilename)
- val parentDir = new File(outputFile.getParent)
+ val parentDir = outputFile.getParentFile()
if (parentDir != null && !parentDir.exists) {
println("making directory: " + parentDir.toString + ": " + parentDir.mkdirs)
}
- FileUtils.copyInputStreamToFile(is, new File(outputFilename))
- println("copied " + outputFilename)
+ 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
+ }
+
+ def writeSupportingClasses(apis: Map[(String, String), List[(String, Operation)]],
+ models: Map[String, Model], apiVersion: String): Seq[File] = {
+
+ val rootDir: Option[File] = Some(new File("."))
+
+ def apiListF(apis: Map[(String, String), List[(String, Operation)]]): List[Map[String, AnyRef]] = {
+ val apiList = new ListBuffer[Map[String, AnyRef]]
+ apis.foreach(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" -> apiToMap(t._1, 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 = writeJson(m._2)
+ modelList += HashMap(
+ "modelName" -> m._1,
+ "model" -> modelToMap(m._1, m._2),
+ "filename" -> config.toModelFilename(m._1),
+ "modelJson" -> json,
+ "hasMoreModels" -> "true")
+ })
+ modelList.size match {
+ case 0 =>
+ case _ => modelList.last.asInstanceOf[HashMap[String, String]] -= "hasMoreModels"
+ }
+
+ modelList.map(_.toMap).toList
+ }
+
+ def dataF(apis: Map[(String, String), List[(String, Operation)]],
+ models: Map[String, Model]): Map[String, AnyRef] =
+ Map(
+ "invokerPackage" -> config.invokerPackage,
+ "package" -> config.packageName,
+ "modelPackage" -> config.modelPackage,
+ "apiPackage" -> config.apiPackage,
+ "apis" -> apiListF(apis),
+ "models" -> modelListF(models),
+ "apiVersion" -> apiVersion) ++ config.additionalParams
+
+ writeSupportingClasses(apis, models, apiVersion, rootDir, dataF)
}
protected def isListType(dt: String) = isCollectionType(dt, "List") || isCollectionType(dt, "Array") || isCollectionType(dt, "Set")
diff --git a/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala
index 161b726503a..5ae7574ad76 100644
--- a/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala
+++ b/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala
@@ -114,91 +114,55 @@ object ScalaAsyncClientGenerator extends App {
}
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) = {
- val engine = new TemplateEngine(rootDir orElse Some(new File(".")))
- val apiList = new ListBuffer[Map[String, AnyRef]]
+ override def writeSupportingClasses(apis: Map[(String, String), List[(String, Operation)]],
+ models: Map[String, Model], apiVersion: String): Seq[File] = {
- 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
- })
- })
-
-
-
- val modelList = new ListBuffer[HashMap[String, AnyRef]]
-
- models.foreach(m => {
- val json = write(m._2)
+ 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.size match {
+ case 0 =>
+ case _ => modelList.last.asInstanceOf[HashMap[String, String]] -= "hasMore"
+ }
+ modelList.map(_.toMap).toList
}
- val data =
+ 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" -> apiList,
- "models" -> modelList)
+ "apis" -> apiListF(apis),
+ "models" -> modelListF(models))
- config.supportingFiles.map(file => {
- val supportingFile = file._1
- val outputDir = file._2
- val destFile = file._3
-
- val outputFilename = outputDir.replaceAll("\\.", File.separator) + File.separator + destFile
- val outputFolder = new File(outputFilename).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(outputFilename, false)
- fw.write(output + "\n")
- fw.close()
- println("wrote " + outputFilename)
- } 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 outputFile = new File(outputFilename)
- val parentDir = new File(outputFile.getParent)
- if (parentDir != null && !parentDir.exists) {
- println("making directory: " + parentDir.toString + ": " + parentDir.mkdirs)
- }
- FileUtils.copyInputStreamToFile(is, new File(outputFilename))
- println("copied " + outputFilename)
- is.close
- }
- }
- })
- //a shutdown method will be added to scalate in an upcoming release
-
- engine.compiler.shutdown()
+ writeSupportingClasses(apis, models, apiVersion, rootDir, dataF)
}
override protected def compileTemplate(templateFile: String, rootDir: Option[File] = None, engine: Option[TemplateEngine] = None): (String, (TemplateEngine, Template)) = {