diff --git a/src/main/java/com/wordnik/swagger/codegen/languages/ScalaClientCodegen.java b/src/main/java/com/wordnik/swagger/codegen/languages/ScalaClientCodegen.java new file mode 100644 index 0000000000..6c845a9ccb --- /dev/null +++ b/src/main/java/com/wordnik/swagger/codegen/languages/ScalaClientCodegen.java @@ -0,0 +1,182 @@ +package com.wordnik.swagger.codegen.languages; + +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; +import java.io.File; + +public class ScalaClientCodegen extends DefaultCodegen implements CodegenConfig { + protected String invokerPackage = "io.swagger.client"; + protected String groupId = "com.wordnik"; + protected String artifactId = "swagger-client"; + protected String artifactVersion = "1.0.0"; + protected String sourceFolder = "src/main/java"; + + public String getName() { + return "scala"; + } + + public String getHelp() { + return "Generates a Scala client library."; + } + + public ScalaClientCodegen() { + super(); + outputFolder = "generated-code/scala"; + modelTemplateFiles.put("model.mustache", ".scala"); + apiTemplateFiles.put("api.mustache", ".scala"); + templateDir = "scala"; + apiPackage = "io.swagger.client.api"; + modelPackage = "io.swagger.client.model"; + + reservedWords = new HashSet ( + Arrays.asList( + "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") + ); + + additionalProperties.put("invokerPackage", invokerPackage); + additionalProperties.put("groupId", groupId); + additionalProperties.put("artifactId", artifactId); + additionalProperties.put("artifactVersion", artifactVersion); + + supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); + supportingFiles.add(new SupportingFile("apiInvoker.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.scala")); + + importMapping.remove("List"); + importMapping.remove("Set"); + importMapping.remove("Map"); + + importMapping.put("DateTime", "org.joda.time.DateTime"); + importMapping.put("ListBuffer", "scala.collections.mutable.ListBuffer"); + + typeMapping = new HashMap(); + typeMapping.put("enum", "NSString"); + typeMapping.put("array", "List"); + typeMapping.put("set", "Set"); + typeMapping.put("boolean", "Boolean"); + typeMapping.put("string", "String"); + typeMapping.put("int", "Int"); + typeMapping.put("long", "Long"); + typeMapping.put("float", "Float"); + typeMapping.put("byte", "Byte"); + typeMapping.put("short", "Short"); + typeMapping.put("char", "Char"); + typeMapping.put("long", "Long"); + typeMapping.put("double", "Double"); + typeMapping.put("object", "Any"); + typeMapping.put("file", "File"); + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "String", + "boolean", + "Boolean", + "Double", + "Int", + "Long", + "Float", + "Object", + "List", + "Map") + ); + instantiationTypes.put("array", "ListBuffer"); + instantiationTypes.put("map", "HashMap"); + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + apiPackage().replaceAll("\\.", "/"); + } + + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + modelPackage().replaceAll("\\.", "/"); + } + + @Override + public String getTypeDeclaration(Property p) { + if(p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "[" + getTypeDeclaration(inner) + "]"; + } + else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + + return getSwaggerType(p) + "[String, " + getTypeDeclaration(inner) + "]"; + } + return super.getTypeDeclaration(p); + } + + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if(typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if(languageSpecificPrimitives.contains(type)) + return toModelName(type); + } + else + type = swaggerType; + return toModelName(type); + } + + @Override + public String toInstantiationType(Property p) { + if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return instantiationTypes.get("map") + "[String, " + inner + "]"; + } + else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return instantiationTypes.get("array") + "[" + inner + "]"; + } + else + return null; + } + + public String toDefaultValue(Property p) { + if(p instanceof StringProperty) + return "null"; + else if (p instanceof BooleanProperty) + return "null"; + else if(p instanceof DateProperty) + return "null"; + else if(p instanceof DateTimeProperty) + return "null"; + else if (p instanceof DoubleProperty) + return "null"; + else if (p instanceof FloatProperty) + return "null"; + else if (p instanceof IntegerProperty) + return "null"; + else if (p instanceof LongProperty) + return "null"; + else if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return "new HashMap[String, " + inner + "]() "; + } + else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return "new ListBuffer[" + inner + "]() "; + } + else + return "null"; + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig b/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig index 6930e09492..bba20b9d0a 100644 --- a/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig +++ b/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig @@ -4,6 +4,7 @@ com.wordnik.swagger.codegen.languages.JaxRSServerCodegen com.wordnik.swagger.codegen.languages.NodeJSServerCodegen com.wordnik.swagger.codegen.languages.ObjcClientCodegen com.wordnik.swagger.codegen.languages.ScalatraServerCodegen +com.wordnik.swagger.codegen.languages.ScalaClientCodegen com.wordnik.swagger.codegen.languages.StaticDocCodegen com.wordnik.swagger.codegen.languages.StaticHtmlGenerator com.wordnik.swagger.codegen.languages.SwaggerGenerator diff --git a/src/main/resources/scala/api.mustache b/src/main/resources/scala/api.mustache index d277a69bdd..7c05406a5a 100644 --- a/src/main/resources/scala/api.mustache +++ b/src/main/resources/scala/api.mustache @@ -26,7 +26,7 @@ class {{classname}} { {{newline}} val contentType = { - {{#bodyParam}}if({{bodyParam}} != null && {{bodyParam}}.isInstanceOf[File] ) + {{#bodyParam}}if({{paramName}} != null && {{paramName}}.isInstanceOf[File] ) "multipart/form-data" else "application/json" {{/bodyParam}} @@ -52,7 +52,7 @@ class {{classname}} { {{/headerParams}} try { - apiInvoker.invokeApi(basePath, path, "{{httpMethod}}", queryParams.toMap, {{#bodyParam}}{{bodyParam}}{{/bodyParam}}{{^bodyParam}}None{{/bodyParam}}, headerParams.toMap, contentType) match { + apiInvoker.invokeApi(basePath, path, "{{httpMethod}}", queryParams.toMap, {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}None{{/bodyParam}}, headerParams.toMap, contentType) match { case s: String => {{#returnType}} Some(ApiInvoker.deserialize(s, "{{returnContainer}}", classOf[{{returnBaseType}}]).asInstanceOf[{{returnType}}]) {{/returnType}} diff --git a/src/main/resources/scala/model.mustache b/src/main/resources/scala/model.mustache index 59b6084dd2..a45b71a8f8 100644 --- a/src/main/resources/scala/model.mustache +++ b/src/main/resources/scala/model.mustache @@ -8,11 +8,8 @@ package {{package}} {{#model}} case class {{classname}} ( - {{#vars}} - - {{#description}}/* {{{description}}} */ - {{/description}} - {{name}}: {{datatype}}{{#hasMore}},{{newline}} {{/hasMore}} - {{/vars}}) + {{#vars}}{{#description}}/* {{{description}}} */ + {{/description}}{{name}}: {{{datatype}}}{{#hasMore}},{{/hasMore}}{{^hasMore}}){{/hasMore}} + {{/vars}} {{/model}} {{/models}} \ No newline at end of file diff --git a/src/main/resources/scala/pom.mustache b/src/main/resources/scala/pom.mustache index 4cb2c261fa..ac6a81caa4 100644 --- a/src/main/resources/scala/pom.mustache +++ b/src/main/resources/scala/pom.mustache @@ -5,7 +5,7 @@ {{artifactId}} jar {{artifactId}} - {{apiVersion}} + {{artifactVersion}} 2.2.0 @@ -186,31 +186,43 @@ ${junit-version} test + + joda-time + joda-time + ${joda-time-version} + + + org.joda + joda-convert + ${joda-version} + - - 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 - - + + 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.2 + 2.2 1.7 4.8.1 1.0.0 diff --git a/swagger.json b/swagger.json deleted file mode 100644 index cf0e5f7e1f..0000000000 --- a/swagger.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "HR API", - "description": "A way to manage people in our organization", - "version": "1.0.0" - }, - "host": "my.api.com", - "basePath": "/v2", - "paths": { - "/": { - "get": { - "tags": [ - "users are awesome" - ], - "parameters": [ - { - "in": "query", - "description": "number of records to skip", - "name": "char", - "type": "integer", - "format": "int32" - } - ], - "responses": { - "200": { - "description": "successful response", - "schema": { - "type": "array", - "items": { - "$ref": "User" - } - } - }, - "400": { - "description": "bad input", - "schema": { - "$ref": "ErrorModel" - } - }, - "default": { - "description": "got a response" - } - } - } - }, - "/users/{id}": { - "get": { - "tags": [ - "users" - ], - "operationId": "getUserById", - "parameters": [ - { - "in": "path", - "name": "id", - "type": "integer", - "format": "int64", - "description": "user id to look up by" - } - ], - "responses": { - "default": { - "description": "got a response" - } - } - } - }, - "/places": { - "get": { - "tags": [ - "locations" - ], - "operationId": "getPlaces", - "responses": { - "default": { - "description": "got a response" - } - } - } - }, - "/photos": { - "get": { - "tags": [ - "users" - ], - "operationId": "getPhotos", - "responses": { - "default": { - "description": "got a response" - } - } - } - } - }, - "definitions": { - "ErrorModel": { - "required": [ - "code", - "message" - ], - "properties": { - "code": { - "type": "integer", - "format": "int64" - }, - "message": { - "type": "string" - } - } - }, - "User": { - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "age": { - "type": "integer", - "format": "int32" - }, - "lastUpdated": { - "type": "string", - "format": "date-time" - } - } - }, - "User2": { - "properties": { - "id": { - "type": "integer", - "format": "int64" - }, - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "age": { - "type": "integer", - "format": "int32" - }, - "lastUpdated": { - "type": "string", - "format": "date-time" - } - } - } - } -}