diff --git a/conf/ruby/sample/build.xml b/conf/ruby/sample/build.xml new file mode 100644 index 00000000000..b482a4eddb7 --- /dev/null +++ b/conf/ruby/sample/build.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/ruby/sample/ivy.xml b/conf/ruby/sample/ivy.xml new file mode 100644 index 00000000000..b2573f73d69 --- /dev/null +++ b/conf/ruby/sample/ivy.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/conf/ruby/sample/ivysettings.xml b/conf/ruby/sample/ivysettings.xml new file mode 100644 index 00000000000..ea8e09b9f5b --- /dev/null +++ b/conf/ruby/sample/ivysettings.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + diff --git a/conf/ruby/sample/java_code_gen_conf.json b/conf/ruby/sample/java_code_gen_conf.json new file mode 100644 index 00000000000..74db34b345c --- /dev/null +++ b/conf/ruby/sample/java_code_gen_conf.json @@ -0,0 +1,27 @@ +{ + "apiUrl":"http://localhost:8002/api/", + + "apiKey":"special-key", + + "defaultServiceBaseClass":"Object", + + "defaultModelBaseClass":"Object", + + "serviceBaseClasses":{}, + + "defaultModelImports":[], + + "defaultServiceImports":[], + + "modelPackageName":"com.wordnik.swagger.sample.sdk.java.model", + + "apiPackageName":"com.wordnik.swagger.sample.sdk.java.api", + + "ignoreMethods":[], + + "ignoreModels":[], + + "outputDirectory":"../swagger-sample-app/sdk-libs/src/main/java/com/wordnik/swagger/sample/sdk/java", + + "libraryHome":"../swagger-sample-app/sdk-libs" +} diff --git a/conf/ruby/sample/lib-test-data.json b/conf/ruby/sample/lib-test-data.json new file mode 100644 index 00000000000..24d529e981d --- /dev/null +++ b/conf/ruby/sample/lib-test-data.json @@ -0,0 +1,42 @@ +{ + "userList":[ + { + "username":"testuser1", + "password":"password1", + "email":"test1@dummy.com" + }, + { + "username":"testuser2", + "password":"password2", + "email":"test2@dummy.com" + } + ], + "petList":[ + { + "id":101, + "name":"pet1", + "photoUrls":["url1","url2"], + "tags":[ + { + "id":1, + "name":"tag1" + }, + { + "id":2, + "name":"tag2" + } + ], + "status":"available", + "category":{"id":1,"name":"cat1"} + } + ], + "orderList":[ + { + "id":101, + "petId":1, + "quantity":1, + "status":"placed", + "shipDate":13456789 + } + ] +} diff --git a/conf/ruby/sample/lib-test-script.json b/conf/ruby/sample/lib-test-script.json new file mode 100644 index 00000000000..7953c939cfb --- /dev/null +++ b/conf/ruby/sample/lib-test-script.json @@ -0,0 +1,265 @@ +{ + "resources" : [ + { + "id" : 1, + "name" : "Find Per by Id", + "httpMethod" : "GET", + "path" : "/pet.{format}/{petId}", + "suggestedMethodName" : "getPetById" + }, + { + "id" : 2, + "name" : "Find pets by status", + "httpMethod" : "GET", + "path" : "/pet.{format}/findByStatus", + "suggestedMethodName" : "findPetsByStatus" + }, + { + "id" : 3, + "name" : "Find pets by tags", + "httpMethod" : "GET", + "path" : "/pet.{format}/findByTags", + "suggestedMethodName" : "findPetsByTags" + }, + { + "id" : 4, + "name" : "Add a pet", + "httpMethod" : "POST", + "path" : "/pet.{format}", + "suggestedMethodName" : "addPet" + }, + { + "id" : 5, + "name" : "Update a pet", + "httpMethod" : "PUT", + "path" : "/pet.{format}", + "suggestedMethodName" : "updatePet" + }, + { + "id" : 6, + "name" : "Create user", + "httpMethod" : "POST", + "path" : "/user.{format}", + "suggestedMethodName" : "createUser" + }, + { + "id" : 7, + "name" : "Update user", + "httpMethod" : "PUT", + "path" : "/user.{format}/{username}", + "suggestedMethodName" : "updateUser" + }, + { + "id" : 8, + "name" : "Delete user", + "httpMethod" : "DELETE", + "path" : "/user.{format}/{username}", + "suggestedMethodName" : "deleteUser" + }, + { + "id" : 9, + "name" : "Get user by user name", + "httpMethod" : "GET", + "path" : "/user.{format}/{username}", + "suggestedMethodName" : "getUserByName" + }, + { + "id" : 10, + "name" : "Login", + "httpMethod" : "GET", + "path" : "/user.{format}/login", + "suggestedMethodName" : "loginUser" + }, + { + "id" : 11, + "name" : "Logout", + "httpMethod" : "GET", + "path" : "/user.{format}/logout", + "suggestedMethodName" : "logoutUser" + }, + { + "id" : 12, + "name" : "Find order by id", + "httpMethod" : "GET", + "path" : "/store.{format}/order/{orderId}", + "suggestedMethodName" : "getOrderById" + }, + { + "id" : 13, + "name" : "Delete order by id", + "httpMethod" : "DELETE", + "path" : "/store.{format}/order/{orderId}", + "suggestedMethodName" : "deleteOrder" + }, + { + "id" : 14, + "name" : "Create order", + "httpMethod" : "POST", + "path" : "/store.{format}/order", + "suggestedMethodName" : "placeOrder" + } + ], + "testSuites" : [ + { + "id" : 1, + "name" : "Test User service related APIs", + "testCases" : [ + { + "name" : "Create User", + "id" : 1, + "resourceId" : 6, + "input" : { + "postData":"${input.userList[0]}" + }, + "assertions" : [ + { + "actualOutput" : "${output(1.1)}", + "condition" : "!=", + "expectedOutput" : "EXCEPTION" + } + ] + }, + { + "name" : "Login User", + "id" : 2, + "resourceId" : 10, + "input" : { + "username":"${input.userList[0].username}", + "password":"${input.userList[0].password}" + }, + "assertions" : [ + { + "actualOutput" : "${output(1.2)}", + "condition" : "!=", + "expectedOutput" : "EXCEPTION" + } + ] + }, + { + "name" : "Find user by name", + "id" : 3, + "resourceId" : 9, + "input" : { + "username":"${input.userList[0].username}" + }, + "assertions" : [ + { + "actualOutput" : "${output(1.3).username}", + "condition" : "==", + "expectedOutput" : "${input.userList[0].username}" + } + ] + }, + { + "name" : "Delete user by name", + "id" : 4, + "resourceId" : 9, + "input" : { + "username":"${input.userList[0].username}" + }, + "assertions" : [ + { + "actualOutput" : "${output(1.4)}", + "condition" : "!=", + "expectedOutput" : "EXCEPTION" + } + ] + } + + + ] + }, + { + "id" : 2, + "name" : "Test Pet service related APIs", + "testCases" : [ + { + "name" : "Add pet", + "id" : 1, + "resourceId" : 4, + "input" : { + "postData":"${input.petList[0]}" + }, + "assertions" : [ + { + "actualOutput" : "${output(2.1)}", + "condition" : "!=", + "expectedOutput" : "EXCEPTION" + } + ] + }, + { + "name" : "Find pet by id", + "id" : 2, + "resourceId" : 1, + "input" : { + "petId":"1" + }, + "assertions" : [ + { + "actualOutput" : "${output(2.2)}", + "condition" : "!=", + "expectedOutput" : "NULL" + } + ] + }, + { + "name" : "Find pet by status", + "id" : 3, + "resourceId" : 2, + "input" : { + "status":"available,sold,pending" + }, + "assertions" : [ + { + "actualOutput" : "${output(2.3).size}", + "condition" : ">", + "expectedOutput" : "0" + } + ] + } + ] + }, + { + "id" : 3, + "name" : "Test Store service related APIs", + "testCases" : [ + { + "name" : "Find order by id", + "id" : 1, + "resourceId" : 12, + "input" : { + "orderId":"1" + }, + "assertions" : [ + { + "actualOutput" : "${output(3.1)}", + "condition" : "!=", + "expectedOutput" : "NULL" + } + ] + }, + { + "name" : "Place order", + "id" : 2, + "resourceId" : 14, + "input" : { + "postData":"${input.orderList[0]}" + }, + "assertions" : [ + { + "actualOutput" : "${output(1.2)}", + "condition" : "!=", + "expectedOutput" : "EXCEPTION" + } + ] + } + ] + } + ] +} + + + + + \ No newline at end of file diff --git a/conf/ruby/structure/swagger.rb b/conf/ruby/structure/swagger.rb new file mode 100644 index 00000000000..5995bad5c15 --- /dev/null +++ b/conf/ruby/structure/swagger.rb @@ -0,0 +1 @@ +# nothing to see yet \ No newline at end of file diff --git a/conf/ruby/templates/EnumObject.st b/conf/ruby/templates/EnumObject.st new file mode 100644 index 00000000000..545ba15eae0 --- /dev/null +++ b/conf/ruby/templates/EnumObject.st @@ -0,0 +1,31 @@ +/** + * Copyright 2011 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 $packageName$ + +$imports:{ import | +import $import$; +}$ + +/** + * $enum.description$ + * NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually. + * @author tony + * + */ +object $className$ { + $values: { value | var $value.name$ = $value.value$};separator="\n"$ +} diff --git a/conf/ruby/templates/ModelObject.st b/conf/ruby/templates/ModelObject.st new file mode 100644 index 00000000000..435bb450f5a --- /dev/null +++ b/conf/ruby/templates/ModelObject.st @@ -0,0 +1,21 @@ +class $className$Model + attr_accessor $fields:{ field | :$field.fieldDefinition.name$};separator=", "$ +$fields:{ field | + $if(field.required)$ validate_presence_of :$field.fieldDefinition.name$$endif$ +}$ + + # TODO: move this to base class + def initialize(attributes = {}) + attributes.symbolize_and_underscore_keys! + + # loop over incoming attributes, only assign to valid attr_accessor props +$fields:{ field | + if(UserModel.respond_to? :$field.fieldDefinition.name$) self.$field.fieldDefinition.name$ = attributes[:$field.fieldDefinition.name$] +}$ + +# if(UserModel.respond_to? :word) self.word = attributes[:word] +# Zap any whitespace and bad encoding +# attributes[:name] &&= attributes[:name].strip.squeeze(' ').force_encoding('UTF-8') +# super(attributes) + end +end \ No newline at end of file diff --git a/conf/ruby/templates/ResourceObject.st b/conf/ruby/templates/ResourceObject.st new file mode 100644 index 00000000000..e69fea3f6c2 --- /dev/null +++ b/conf/ruby/templates/ResourceObject.st @@ -0,0 +1,47 @@ +module $resource$ + +$methods:{ method | + def $method.name$(opts={}) +$if(method.pathParameters)$ requiredKeys=[:$method.pathParameters:{ param | $param.name$};separator=", "$]$endif$ +$if(method.queryParameters)$ queryparamKeys=[:$method.queryParameters:{ param | $param.name$};separator=", "$]$endif$ + +$if(method.pathParameters)$ + #check required options + requiredKeys.each do |key| + raise "#{key} is required" unless options.has_key?(key) + end +$endif$ + + + # set default values and merge with input + options = { +$if(method.arguments)$$method.arguments:{ param | $if(param.defaultValue)$ :$param.name$="$param.defaultValue$"$endif$}$$endif$ + }.merge(opts) + + #resource path + path = "$method.resourcePath$".sub('{format}', '.json') + +$if(method.pathParameters)$ + # sub pathparams +$method.pathParameters:{ param | + path.sub!('{$param.name$}', URI.encode(options[:$param.name$])) +}$$endif$ + #pull querystring keys from options + queryopts = options.select do |key,value| + queryparamKeys.include? key + end + +$if(method.hasResponseValue)$ + results = Swagger::request.new(:get, path, queryopts, nil) +$if(method.returnValueList)$ + output = results.map {|result| $method.returnValue$.new(result)} +$else$ + output = $method.returnValue$.new(result) +$endif$ +$else$ + Swagger::request.new(:get, path, queryopts, nil) +$endif$ + + end + +}$ diff --git a/conf/ruby/templates/VersionChecker.st b/conf/ruby/templates/VersionChecker.st new file mode 100644 index 00000000000..134fc8e0a2c --- /dev/null +++ b/conf/ruby/templates/VersionChecker.st @@ -0,0 +1,5 @@ +module $resource$ + def get_compatible_version(*args) + '$apiVersion$' + end + \ No newline at end of file diff --git a/src/main/java/com/wordnik/swagger/codegen/MethodArgument.java b/src/main/java/com/wordnik/swagger/codegen/MethodArgument.java index b3639c23c71..a5b72216843 100644 --- a/src/main/java/com/wordnik/swagger/codegen/MethodArgument.java +++ b/src/main/java/com/wordnik/swagger/codegen/MethodArgument.java @@ -24,15 +24,29 @@ public class MethodArgument { public static String ARGUMENT_OBJECT = "Object"; private String name; - private String description; - private String dataType; - private String allowedValues; - private String inputModelClassArgument; private String methodNameFromModelClass; + private String defaultValue; + private boolean required; + + public String getDefaultValue(){ + return defaultValue; + } + + public void setDefaultValue(String defaultValue){ + this.defaultValue = defaultValue; + } + + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required){ + this.required = required; + } public String getName() { return name; diff --git a/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java b/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java index 1577e7bdc9e..0583f562aa3 100644 --- a/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java +++ b/src/main/java/com/wordnik/swagger/codegen/config/LanguageConfiguration.java @@ -52,17 +52,32 @@ public class LanguageConfiguration { } public void setOutputDirectory(String outputDirectory) { - if(outputDirectory == null || outputDirectory.length() == 0){ throw new CodeGenerationException("Error creating output path : Output path was null "); } outputDirectory = outputDirectory.endsWith("/") ? outputDirectory.substring(0, outputDirectory.lastIndexOf("/")) : outputDirectory; - this.modelClassLocation = outputDirectory + "/model/"; this.resourceClassLocation = outputDirectory + "/api/"; } + public void setOutputDirectory(String outputDirectory, String modelDirectory, String resourceDirectory){ + if(outputDirectory == null || outputDirectory.length() == 0){ + throw new CodeGenerationException("Error creating output path : Output path was null "); + } + outputDirectory = outputDirectory.endsWith("/") ? outputDirectory.substring(0, outputDirectory.lastIndexOf("/")) : outputDirectory; + + // add leading + trailing slashes + if(!modelDirectory.startsWith("/")) modelDirectory = "/" + modelDirectory; + if(!modelDirectory.endsWith("/")) modelDirectory = modelDirectory + "/"; + + if(!resourceDirectory.startsWith("/")) resourceDirectory = "/" + resourceDirectory; + if(!resourceDirectory.endsWith("/")) resourceDirectory = resourceDirectory + "/"; + + this.modelClassLocation = outputDirectory + modelDirectory; + this.resourceClassLocation = outputDirectory + resourceDirectory; + } + public String getModelClassLocation() { return modelClassLocation; } diff --git a/src/main/java/com/wordnik/swagger/codegen/config/ruby/RubyDataTypeMappingProvider.scala b/src/main/java/com/wordnik/swagger/codegen/config/ruby/RubyDataTypeMappingProvider.scala new file mode 100644 index 00000000000..2b7cce7efa9 --- /dev/null +++ b/src/main/java/com/wordnik/swagger/codegen/config/ruby/RubyDataTypeMappingProvider.scala @@ -0,0 +1,200 @@ +/** + * Copyright 2011 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.config.ruby + +import com.wordnik.swagger.codegen.config.DataTypeMappingProvider + +import com.wordnik.swagger.codegen.config.NamingPolicyProvider +import com.wordnik.swagger.codegen.config.common.UnderscoreNamingPolicyProvider + +import scala.collection.mutable._ +import scala.collection.JavaConversions._ + +object RubyDataTypeMappingProvider { + val primitiveValueMap = Map("string" -> "String", + "String" -> "String", + "int" -> "int", + "integer" -> "int", + "Integer" -> "int", + "boolean" -> "boolean", + "Boolean" -> "boolean", + "long" -> "long", + "Long" -> "long", + "float" -> "float", + "Float" -> "float", + "Date" -> "Date", + "date" -> "Date") + + val primitiveObjectMap = Map("string" -> "String", + "String" -> "String", + "java.lang.String" -> "String", + "int" -> "Integer", + "integer" -> "Integer", + "Integer" -> "Integer", + "java.lang.Integer" -> "Integer", + "boolean" -> "Boolean", + "Boolean" -> "Boolean", + "java.lang.Boolean" -> "Boolean", + "long" -> "Long", + "Long" -> "Long", + "java.lang.Long" -> "Long", + "float" -> "Float", + "Float" -> "Float", + "java.lang.Float" -> "Float", + "Date" -> "Date", + "date" -> "Date", + "java.util.Date" -> "Date") +} + +class RubyDataTypeMappingProvider extends DataTypeMappingProvider { + val nameGenerator = new UnderscoreNamingPolicyProvider() + + def isPrimitiveType(input: String): Boolean = { + RubyDataTypeMappingProvider.primitiveObjectMap.contains(input) match { + case true => true + case _ => false + } + } + + def getListReturnTypeSignature(typeClass: String): String = { + return "List[" + nameGenerator.applyClassNamingPolicy(typeClass) + "]"; + } + + def getMapReturnTypeSignature(typeClass: String): String = { + return "Map[" + nameGenerator.applyClassNamingPolicy(typeClass) + "]"; + } + + def getSetReturnTypeSignature(typeClass: String): String = { + return "Set[" + nameGenerator.applyClassNamingPolicy(typeClass) + "]"; + } + + def generateVariableInitialization(typeClass:String):String = "=_" + + def generateListInitialization(typeClass: String): String = { + return " new ListBuffer[" + nameGenerator.applyClassNamingPolicy(typeClass) + "]"; + } + + def generateMapInitialization(typeClass: String): String = { + return " new HashMap[" + nameGenerator.applyClassNamingPolicy(typeClass) + "]"; + } + + def generateSetInitialization(typeClass: String): String = { + return " new HashSet[" + nameGenerator.applyClassNamingPolicy(typeClass) + "]"; + } + + def getListIncludes(): java.util.List[String] = { + List("scala.collection.mutable.ListBuffer") + } + + def getMapIncludes(): java.util.List[String] = { + List("java.util.Map", "java.util.HashMap") + } + + def getSetIncludes: java.util.List[String] = { + List("java.util.Set", "java.util.HashSet") + } + + def getDateIncludes: java.util.List[String] = { + List("java.util.Date") + } + + /** + * Gets the short name of the class the class. + * Input can be MAP, LIST or regular string. In case of map or list the class name will be class name + * that map or list is returning. + * @param type + * @return + */ + def getGenericType(inputType: String): String = { + var classShortName = "" + if (inputType.startsWith("List[")) { + classShortName = inputType.substring(5, inputType.length() - 1); + classShortName = getClassType(classShortName, true); + } else if (inputType.startsWith("Map[")) { + classShortName = inputType.substring(4, inputType.length() - 1) + classShortName = getClassType(classShortName, true) + } else if (inputType.startsWith("Set[")) { + classShortName = inputType.substring(4, inputType.length() - 1) + classShortName = getClassType(classShortName, true) + } else if (inputType.equalsIgnoreCase("ok")) { + classShortName = "" + } else { + classShortName = getClassType(inputType, true) + } + classShortName + } + + /** + * Returns the syntax for defintion of an object of type and name + * + * @param argumentType + * @param argumentName + * @return + */ + def getArgumentDefinition(argumentType: String, argumentName: String): String = { + argumentName + ":" + argumentType + } + + /** + * Gets the class of the expected return value for a type string. Examples of type Strings are int, User, List[User] + * If the type string is a collection type like a map or list the string value returned would be the class + * that map or list is returning. + * + * @param type + * @return + */ + def getClassType(input: String, primitiveObject: Boolean): String = { + if (input.equalsIgnoreCase("void") || input.equalsIgnoreCase("ok")) { + "" + } else { + var classShortName = "" + if (input.startsWith("List[")) { + classShortName = input.substring(5, input.length() - 1); + classShortName = "List[" + getClassName(classShortName, true) + "]"; + } else if (input.startsWith("Map[")) { + classShortName = input.substring(4, input.length() - 1); + classShortName = "Map[" + getClassName(classShortName, true) + "]"; + } else if (input.startsWith("Set[")) { + classShortName = input.substring(4, input.length() - 1); + classShortName = "Set[" + getClassName(classShortName, true) + "]"; + } else { + classShortName = getClassName(input, true); + } + classShortName + } + } + + /** + * If the data type is primitive and it is expecting object structure then return primitive objects + * else return primitive types + * @param type + * @param primitiveObject -- indicates if the object is primitive or not + * @return + */ + def getClassName(input: String, primitiveObject: Boolean): String = { + isPrimitiveType(input) match { + case true => { + if (primitiveObject) { + RubyDataTypeMappingProvider.primitiveObjectMap(input) + } else { + RubyDataTypeMappingProvider.primitiveValueMap(input) + } + } + case _ => nameGenerator.applyClassNamingPolicy(input) + } + } +} diff --git a/src/main/java/com/wordnik/swagger/codegen/config/ruby/RubyLibCodeGen.scala b/src/main/java/com/wordnik/swagger/codegen/config/ruby/RubyLibCodeGen.scala new file mode 100644 index 00000000000..094a049095f --- /dev/null +++ b/src/main/java/com/wordnik/swagger/codegen/config/ruby/RubyLibCodeGen.scala @@ -0,0 +1,99 @@ +/** + * Copyright 2011 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.config.ruby + +import com.wordnik.swagger.codegen.LibraryCodeGenerator +import com.wordnik.swagger.codegen.config.LanguageConfiguration +import com.wordnik.swagger.codegen.config.common.UnderscoreNamingPolicyProvider +import com.wordnik.swagger.codegen.exception.CodeGenerationException +import com.wordnik.swagger.codegen.util.FileUtil +import java.io.File +import com.wordnik.swagger.codegen.resource.EndpointOperation + +object RubyLibCodeGen { + def main(args: Array[String]) = { + val codeGenerator = args.length match { + case 1 => new RubyLibCodeGen(args(0)) + case 4 => { + var apiServerURL = args(0) + if (!apiServerURL.endsWith("/")) { + apiServerURL = apiServerURL + "/" + } + val apiKey = args(1); + val packageName = args(2) + var libraryHome = args(3) + if (libraryHome.endsWith("/")) { + libraryHome = libraryHome.substring(0, libraryHome.length() - 1) + } + val modelPackageName = packageName + ".models" + val apiPackageName = packageName + ".resources" + val classOutputDir = libraryHome + "/src/main/ruby/lib/" + packageName.replace(".", "/") + new RubyLibCodeGen(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome) + } + case _ => throw new CodeGenerationException("Invalid number of arguments passed: No command line argument was passed to the program for config json") + } + codeGenerator.generateCode() + } +} + +class RubyLibCodeGen ( + apiServerURL: String, + apiKey: String, + modelPackageName: String, + apiPackageName: String, + classOutputDir: String, + libraryHome: String, + configPath: String) extends LibraryCodeGenerator { + + // don't want to generate input models + EndpointOperation.setArgCountForInputModel(10000) + + if (null != configPath) { + initializeWithConfigPath(configPath) + this.setDataTypeMappingProvider(new RubyDataTypeMappingProvider()) + this.setNameGenerator(new UnderscoreNamingPolicyProvider()) + } + else{ + initialize(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome) + setDataTypeMappingProvider(new RubyDataTypeMappingProvider()) + setNameGenerator(new UnderscoreNamingPolicyProvider()) + } + + def this(apiServerURL: String, apiKey: String, modelPackageName: String, apiPackageName: String, classOutputDir: String, libraryHome: String) = this(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome, null) + def this(configPath: String) = this(null, null, null, null, null, null, configPath) + + override def initializeLangConfig(config: LanguageConfiguration): LanguageConfiguration = { + config.setClassFileExtension(".rb"); + config.setTemplateLocation("conf/ruby/templates"); + config.setStructureLocation("conf/ruby/structure"); + config.setExceptionPackageName("com.wordnik.swagger.exception"); + config.setAnnotationPackageName("com.wordnik.swagger.annotations"); + + config.setOutputDirectory(classOutputDir, "models", "resources"); + + //create ouput directories + FileUtil.createOutputDirectories(config.getModelClassLocation(), config.getClassFileExtension()); + FileUtil.createOutputDirectories(config.getResourceClassLocation(), config.getClassFileExtension()); + FileUtil.clearFolder(config.getModelClassLocation()); + FileUtil.clearFolder(config.getResourceClassLocation()); + FileUtil.clearFolder(config.getLibraryHome() + "/src/main/ruby/com/wordnik/swagger/runtime"); + FileUtil.createOutputDirectories(config.getLibraryHome() + "/src/main/ruby/lib", "ruby"); + FileUtil.copyDirectory(new File(config.getStructureLocation()), new File(classOutputDir)); + + config + } +} diff --git a/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java b/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java index 050958bd0c3..10f76e2766e 100644 --- a/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java +++ b/src/main/java/com/wordnik/swagger/codegen/resource/EndpointOperation.java @@ -30,7 +30,6 @@ import java.util.List; * Time: 7:54 AM */ public class EndpointOperation { - public static String PARAM_TYPE_QUERY = "query"; public static String PARAM_TYPE_PATH = "path"; public static String PARAM_TYPE_BODY = "body"; @@ -41,7 +40,9 @@ public class EndpointOperation { private static String API_KEY_PARAM_NAME = "api_key"; private static String FORMAT_PARAM_NAME = "format"; - private static String AUTH_TOKEN_ARGUMENT_NAME = "authToken"; + private static String AUTH_TOKEN_ARGUMENT_NAME = "authToken"; + + private static int ARG_COUNT_FOR_INPUT_MODEL = 4; private String httpMethod; @@ -64,6 +65,14 @@ public class EndpointOperation { private String nickname; private List errorResponses; + + public static int getArgCountForInputModel(){ + return ARG_COUNT_FOR_INPUT_MODEL; + } + + public static void setArgCountForInputModel(int argCount){ + ARG_COUNT_FOR_INPUT_MODEL = argCount; + } public List getErrorResponses() { return errorResponses; @@ -221,6 +230,8 @@ public class EndpointOperation { anArgument.setName(AUTH_TOKEN_ARGUMENT_NAME); anArgument.setDataType(MethodArgument.ARGUMENT_STRING); anArgument.setDescription(modelField.getDescription()); + anArgument.setRequired(modelField.isRequired()); + anArgument.setDefaultValue(modelField.getDefaultValue()); arguments.add(anArgument); }else if(modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_HEADER) && modelField.getName().equals(API_KEY_PARAM_NAME)){ @@ -230,12 +241,16 @@ public class EndpointOperation { anArgument.setName(modelField.getName()); anArgument.setDataType(MethodArgument.ARGUMENT_STRING); anArgument.setDescription(modelField.getDescription()); + anArgument.setRequired(true); // always true + anArgument.setDefaultValue(modelField.getDefaultValue()); arguments.add(anArgument); pathParams.add(anArgument); }else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_QUERY)) { anArgument.setName(modelField.getName()); anArgument.setDataType(MethodArgument.ARGUMENT_STRING); anArgument.setDescription(modelField.getDescription()); + anArgument.setRequired(modelField.isRequired()); + anArgument.setDefaultValue(modelField.getDefaultValue()); queryParams.add(anArgument); arguments.add(anArgument); }else if (modelField.getParamType().equalsIgnoreCase(PARAM_TYPE_BODY)) { @@ -245,6 +260,8 @@ public class EndpointOperation { anArgument.setName(modelField.getName()); anArgument.setDataType(dataTypeMapper.getClassType(modelField.getDataType(), false)); anArgument.setDescription(modelField.getDescription()); + anArgument.setRequired(modelField.isRequired()); + anArgument.setDefaultValue(modelField.getDefaultValue()); arguments.add(anArgument); method.setPostObject(true); } @@ -259,7 +276,7 @@ public class EndpointOperation { } //check for number of arguments, if we have more than 4 then send the arguments as input object - if(method.getArguments() != null && method.getArguments().size() > 4){ + if(method.getArguments() != null && method.getArguments().size() > ARG_COUNT_FOR_INPUT_MODEL){ List arguments = new ArrayList(); Model modelforMethodInput = new Model(); modelforMethodInput.setName(inputobjectName);