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 + } +}