From e542fbd0a296dd3b0d76c3f049f789b08717a36d Mon Sep 17 00:00:00 2001 From: James Earl Douglas Date: Thu, 24 Apr 2014 15:07:45 -0700 Subject: [PATCH 1/3] De-duplicate code from Codegen#writeSupportingClasses --- .../com/wordnik/swagger/codegen/Codegen.scala | 108 +++++++++++------- .../codegen/ScalaAsyncClientGenerator.scala | 98 +++++----------- 2 files changed, 96 insertions(+), 110 deletions(-) diff --git a/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala b/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala index 1cc22f72aa..675c7cd179 100644 --- a/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala +++ b/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala @@ -555,60 +555,28 @@ 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]): Unit = { - 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 - }) - }) - - 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 + val engine = new TemplateEngine(rootDir orElse Some(new File("."))) + val data = dataF(apis, models) config.supportingFiles.map(file => { val supportingFile = file._1 val outputDir = file._2 val destFile = file._3 - val outputFilename = outputDir + File.separator + destFile + 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, Some(rootDir), Some(engine)) + val (resourceName, (_, template)) = compileTemplate(supportingFile, rootDir, Some(engine)) engine.layout(resourceName, template, data.toMap) } val fw = new FileWriter(outputFilename, false) @@ -617,7 +585,7 @@ class Codegen(config: CodegenConfig) { println("wrote " + outputFilename) } 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) @@ -638,6 +606,60 @@ class Codegen(config: CodegenConfig) { engine.compiler.shutdown() } + def writeSupportingClasses(apis: Map[(String, String), List[(String, Operation)]], + models: Map[String, Model], apiVersion: String): Unit = { + + 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") protected def isMapType(dt: String) = isCollectionType(dt, "Map") diff --git a/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala index 161b726503..2541cf046e 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): Unit = { - 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)) = { From 666a4be1f282547ec33c087d64dc469d78374da4 Mon Sep 17 00:00:00 2001 From: James Earl Douglas Date: Thu, 24 Apr 2014 15:12:11 -0700 Subject: [PATCH 2/3] Return files generated from Codegen#writeSupportingClasses --- .../com/wordnik/swagger/codegen/Codegen.scala | 25 ++++++++++--------- .../codegen/ScalaAsyncClientGenerator.scala | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala b/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala index 675c7cd179..3aa72cbe97 100644 --- a/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala +++ b/src/main/scala/com/wordnik/swagger/codegen/Codegen.scala @@ -560,18 +560,18 @@ class Codegen(config: CodegenConfig) { models: Map[String, Model], apiVersion: String, rootDir: Option[File], - dataF: (Map[(String, String), List[(String, Operation)]], Map[String, Model]) => Map[String, AnyRef]): Unit = { + dataF: (Map[(String, String), List[(String, Operation)]], Map[String, Model]) => Map[String, AnyRef]): Seq[File] = { val engine = new TemplateEngine(rootDir orElse Some(new File("."))) val data = dataF(apis, models) - 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.replaceAll("\\.", File.separator) + 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")) { @@ -579,10 +579,10 @@ class Codegen(config: CodegenConfig) { 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()) { @@ -591,23 +591,24 @@ class Codegen(config: CodegenConfig) { 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): Unit = { + models: Map[String, Model], apiVersion: String): Seq[File] = { val rootDir: Option[File] = Some(new File(".")) diff --git a/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala index 2541cf046e..5ae7574ad7 100644 --- a/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala +++ b/src/main/scala/com/wordnik/swagger/codegen/ScalaAsyncClientGenerator.scala @@ -116,7 +116,7 @@ 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): Unit = { + 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]] From 94ad254a588287c65d0b86eb7770c6d99a8ceeb6 Mon Sep 17 00:00:00 2001 From: James Earl Douglas Date: Thu, 24 Apr 2014 15:14:41 -0700 Subject: [PATCH 3/3] Return files generated from BasicGenerator#generateClientWithoutExit --- .../scala/com/wordnik/swagger/codegen/BasicGenerator.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/com/wordnik/swagger/codegen/BasicGenerator.scala b/src/main/scala/com/wordnik/swagger/codegen/BasicGenerator.scala index bd660d9972..87f1906539 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/") }