updated to support raw swagger types

This commit is contained in:
Tony Tam 2012-08-29 16:54:14 -07:00
parent 6113826180
commit 5482cb7822
5 changed files with 34 additions and 17 deletions

View File

@ -41,7 +41,7 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
override def apiPackage: Option[String] = Some("com.wordnik.client.api") override def apiPackage: Option[String] = Some("com.wordnik.client.api")
var codegen = new Codegen(this) var codegen = new Codegen(this)
def m = JsonUtil.getJsonMapper def json = ScalaJsonUtil.getJsonMapper
def generateClient(args: Array[String]) = { def generateClient(args: Array[String]) = {
if (args.length == 0) { if (args.length == 0) {
@ -54,8 +54,8 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
} }
val doc = { val doc = {
try { try {
val json = ResourceExtractor.extractListing(getResourcePath(host), apiKey) val jsonString = ResourceExtractor.extractListing(getResourcePath(host), apiKey)
m.readValue(json, classOf[Documentation]) json.readValue(jsonString, classOf[Documentation])
} catch { } catch {
case e: Exception => throw new Exception("unable to read from " + host, e) case e: Exception => throw new Exception("unable to read from " + host, e)
} }
@ -91,12 +91,14 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
}) })
val apiMap = groupApisToFiles(operations.toList) val apiMap = groupApisToFiles(operations.toList)
for ((identifier, operationList) <- apiMap) { for ((identifier, operationList) <- apiMap) {
val basePath = identifier._1 val basePath = identifier._1
val className = identifier._2 val name = identifier._2
val className = toApiName(name)
val m = new HashMap[String, AnyRef] val m = new HashMap[String, AnyRef]
m += "name" -> className m += "name" -> name
m += "className" -> className
m += "basePath" -> basePath m += "basePath" -> basePath
m += "package" -> apiPackage m += "package" -> apiPackage
m += "invokerPackage" -> invokerPackage m += "invokerPackage" -> invokerPackage
@ -104,6 +106,9 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
m += "models" -> None m += "models" -> None
m += "outputDirectory" -> (destinationDir + File.separator + apiPackage.getOrElse("").replaceAll("\\.", File.separator)) m += "outputDirectory" -> (destinationDir + File.separator + apiPackage.getOrElse("").replaceAll("\\.", File.separator))
m += "newline" -> "\n" m += "newline" -> "\n"
// println(json.writeValueAsString(m))
for ((file, suffix) <- apiTemplateFiles) { for ((file, suffix) <- apiTemplateFiles) {
m += "filename" -> (className + suffix) m += "filename" -> (className + suffix)
generateAndWrite(m.toMap, file) generateAndWrite(m.toMap, file)
@ -115,6 +120,7 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
if (!defaultIncludes.contains(name)) { if (!defaultIncludes.contains(name)) {
val m = new HashMap[String, AnyRef] val m = new HashMap[String, AnyRef]
m += "name" -> name m += "name" -> name
m += "className" -> name
m += "apis" -> None m += "apis" -> None
m += "models" -> List((name, schema)) m += "models" -> List((name, schema))
m += "package" -> modelPackage m += "package" -> modelPackage
@ -131,8 +137,6 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
codegen.writeSupportingClasses(apiMap.toMap, allModels.toMap) codegen.writeSupportingClasses(apiMap.toMap, allModels.toMap)
} }
def apiNameFromPath(apiPath: String) = makeApiNameFromPath(apiPath)
def generateAndWrite(bundle: Map[String, AnyRef], templateFile: String) = { def generateAndWrite(bundle: Map[String, AnyRef], templateFile: String) = {
val output = codegen.generateSource(bundle, templateFile) val output = codegen.generateSource(bundle, templateFile)
val outputDir = new File(bundle("outputDirectory").asInstanceOf[String]) val outputDir = new File(bundle("outputDirectory").asInstanceOf[String])
@ -148,7 +152,7 @@ abstract class BasicGenerator extends CodegenConfig with PathUtil {
def groupApisToFiles(operations: List[(String /*basePath*/ , String /*apiPath*/ , DocumentationOperation /* operation*/ )]): Map[(String, String), ListBuffer[(String, DocumentationOperation)]] = { def groupApisToFiles(operations: List[(String /*basePath*/ , String /*apiPath*/ , DocumentationOperation /* operation*/ )]): Map[(String, String), ListBuffer[(String, DocumentationOperation)]] = {
val opMap = new HashMap[(String, String), ListBuffer[(String, DocumentationOperation)]] val opMap = new HashMap[(String, String), ListBuffer[(String, DocumentationOperation)]]
for ((basePath, apiPath, operation) <- operations) { for ((basePath, apiPath, operation) <- operations) {
val className = apiNameFromPath(apiPath) val className = resourceNameFromFullPath(apiPath)
val listToAddTo = opMap.getOrElse((basePath, className), { val listToAddTo = opMap.getOrElse((basePath, className), {
val l = new ListBuffer[(String, DocumentationOperation)] val l = new ListBuffer[(String, DocumentationOperation)]
opMap += (basePath, className) -> l opMap += (basePath, className) -> l

View File

@ -146,6 +146,7 @@ class Codegen(config: CodegenConfig) {
var data = Map[String, AnyRef]( var data = Map[String, AnyRef](
"name" -> bundle("name"), "name" -> bundle("name"),
"package" -> bundle("package"), "package" -> bundle("package"),
"className" -> bundle("className"),
"invokerPackage" -> bundle("invokerPackage"), "invokerPackage" -> bundle("invokerPackage"),
"imports" -> imports, "imports" -> imports,
"operations" -> f, "operations" -> f,
@ -192,7 +193,6 @@ class Codegen(config: CodegenConfig) {
def apiToMap(path: String, op: DocumentationOperation): Map[String, AnyRef] = { def apiToMap(path: String, op: DocumentationOperation): Map[String, AnyRef] = {
var bodyParam: Option[String] = None var bodyParam: Option[String] = None
var queryParams = new ListBuffer[AnyRef] var queryParams = new ListBuffer[AnyRef]
val pathParams = new ListBuffer[AnyRef] val pathParams = new ListBuffer[AnyRef]
val headerParams = new ListBuffer[AnyRef] val headerParams = new ListBuffer[AnyRef]
@ -202,10 +202,11 @@ class Codegen(config: CodegenConfig) {
if (op.getParameters != null) { if (op.getParameters != null) {
op.getParameters.foreach(param => { op.getParameters.foreach(param => {
val params = new HashMap[String, AnyRef] val params = new HashMap[String, AnyRef]
params += (param.paramType + "Param") -> "true" params += (param.paramType + "Parameter") -> "true"
params += "type" -> param.paramType params += "type" -> param.paramType
params += "defaultValue" -> config.toDefaultValue(param.dataType, param.defaultValue) params += "defaultValue" -> config.toDefaultValue(param.dataType, param.defaultValue)
params += "dataType" -> config.toDeclaredType(param.dataType) params += "dataType" -> config.toDeclaredType(param.dataType)
params += "swaggerDataType" -> param.dataType
params += "description" -> param.description params += "description" -> param.description
params += "hasMore" -> "true" params += "hasMore" -> "true"
params += "allowMultiple" -> param.allowMultiple.toString params += "allowMultiple" -> param.allowMultiple.toString
@ -448,6 +449,7 @@ class Codegen(config: CodegenConfig) {
apis.foreach(a => { apis.foreach(a => {
apiList += Map( apiList += Map(
"name" -> a._1._2, "name" -> a._1._2,
"className" -> config.toApiName(a._1._2),
"basePath" -> a._1._1, "basePath" -> a._1._1,
"operations" -> { "operations" -> {
(for (t <- a._2) yield { Map("operation" -> t._2, "path" -> t._1) }).toList (for (t <- a._2) yield { Map("operation" -> t._2, "path" -> t._1) }).toList
@ -472,6 +474,7 @@ class Codegen(config: CodegenConfig) {
HashMap( HashMap(
"package" -> config.packageName, "package" -> config.packageName,
"modelPackage" -> config.modelPackage, "modelPackage" -> config.modelPackage,
"apiPackage" -> config.apiPackage,
"apis" -> apiList, "apis" -> apiList,
"models" -> modelList) "models" -> modelList)

View File

@ -37,8 +37,17 @@ trait PathUtil {
} }
} }
def makeApiNameFromPath(apiPath: String) = { def toApiName(name: String) = {
val name = apiPath.split("/")(1).split("\\.")(0).replaceAll("/", "")
name.charAt(0).toUpperCase + name.substring(1) + "Api" name.charAt(0).toUpperCase + name.substring(1) + "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

@ -41,6 +41,7 @@ abstract class CodegenConfig {
def modelPackage: Option[String] = None def modelPackage: Option[String] = None
def escapeReservedWord(word: String) = word def escapeReservedWord(word: String) = word
def toApiName(name: String): String
def apiNameFromPath(apiPath: String): String def apiNameFromPath(apiPath: String): String
// only process these apis (by name) // only process these apis (by name)

View File

@ -263,7 +263,7 @@ class SwaggerSpecValidator(private val doc: Documentation,
case Some(updatedName) => { case Some(updatedName) => {
if (!p.dataType.equals(updatedName)) { if (!p.dataType.equals(updatedName)) {
// LOGGER.finest("--> updated " + dataType + " to " + updatedName) // LOGGER.finest("--> updated " + dataType + " to " + updatedName)
!!(p, OPERATION_PARAM, format("%s.%s(body: %s)", makeApiNameFromPath(api.getPath()), op.nickname, p.dataType), format("Invalid data type %s. Best guess: %s", p.dataType, updatedName)) !!(p, OPERATION_PARAM, format("%s.%s(body: %s)", apiNameFromPath(api.getPath()), op.nickname, p.dataType), format("Invalid data type %s. Best guess: %s", p.dataType, updatedName))
if (fix) p.dataType = updatedName if (fix) p.dataType = updatedName
} }
} }
@ -274,7 +274,7 @@ class SwaggerSpecValidator(private val doc: Documentation,
getUpdatedType(validModelNames, dataType) match { getUpdatedType(validModelNames, dataType) match {
case Some(updatedName) => { case Some(updatedName) => {
// LOGGER.finest("--> updated " + dataType + " to " + updatedName) // LOGGER.finest("--> updated " + dataType + " to " + updatedName)
!!(p, OPERATION_PARAM, format("%s.%s(path_%s: %s)", makeApiNameFromPath(api.getPath()), op.nickname, p.name, p.dataType), format("Invalid data type %s. Best guess: %s", p.dataType, updatedName)) !!(p, OPERATION_PARAM, format("%s.%s(path_%s: %s)", apiNameFromPath(api.getPath()), op.nickname, p.name, p.dataType), format("Invalid data type %s. Best guess: %s", p.dataType, updatedName))
if (fix) p.dataType = updatedName if (fix) p.dataType = updatedName
} }
case _ => // leave it alone case _ => // leave it alone
@ -284,7 +284,7 @@ class SwaggerSpecValidator(private val doc: Documentation,
getUpdatedType(validModelNames, dataType) match { getUpdatedType(validModelNames, dataType) match {
case Some(updatedName) => { case Some(updatedName) => {
// LOGGER.finest("--> updated " + dataType + " to " + updatedName) // LOGGER.finest("--> updated " + dataType + " to " + updatedName)
!!(p, OPERATION_PARAM, format("%s.%s(query_%s: %s)", makeApiNameFromPath(api.getPath()), op.nickname, p.name, p.dataType), format("Invalid %s. Best guess: %s", p.dataType, updatedName)) !!(p, OPERATION_PARAM, format("%s.%s(query_%s: %s)", apiNameFromPath(api.getPath()), op.nickname, p.name, p.dataType), format("Invalid %s. Best guess: %s", p.dataType, updatedName))
if (fix) p.dataType = updatedName if (fix) p.dataType = updatedName
} }
case _ => // leave it alone case _ => // leave it alone
@ -316,7 +316,7 @@ class SwaggerSpecValidator(private val doc: Documentation,
case Some(updatedName) => { case Some(updatedName) => {
if (!responseClass.equals(updatedName)) { if (!responseClass.equals(updatedName)) {
LOGGER.finest("--> updated " + responseClass + " to " + updatedName) LOGGER.finest("--> updated " + responseClass + " to " + updatedName)
!!(op, OPERATION, format("%s.%s(): %s", makeApiNameFromPath(api.getPath()), op.nickname, op.responseClass), format("Invalid response class. Best guess: %s", updatedName)) !!(op, OPERATION, format("%s.%s(): %s", apiNameFromPath(api.getPath()), op.nickname, op.responseClass), format("Invalid response class. Best guess: %s", updatedName))
if (fix) op.responseClass = updatedName if (fix) op.responseClass = updatedName
} }
} }