diff --git a/bin/all-petstore.sh b/bin/all-petstore.sh index 0f97790e75a..72797973a32 100755 --- a/bin/all-petstore.sh +++ b/bin/all-petstore.sh @@ -27,6 +27,7 @@ cd $APP_DIR ./bin/qt5-petstore.sh ./bin/php-petstore.sh ./bin/python-petstore.sh +./bin/retrofit-petstore.sh ./bin/ruby-petstore.sh ./bin/objc-petstore.sh ./bin/scala-petstore.sh diff --git a/bin/retrofit-petstore.sh b/bin/retrofit-petstore.sh new file mode 100755 index 00000000000..10b82e61963 --- /dev/null +++ b/bin/retrofit-petstore.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/retrofit -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l retrofit -o samples/client/petstore/retrofit" + +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java index 7f8d390f371..76055110b92 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/CodegenOperation.java @@ -7,7 +7,7 @@ import java.util.*; public class CodegenOperation { public Boolean hasConsumes, hasProduces, hasParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMapContainer, isListContainer, - hasMore = Boolean.TRUE; + hasMore = Boolean.TRUE, isMultipart; public String path, operationId, returnType, httpMethod, returnBaseType, returnContainer, summary, notes, baseName, defaultResponse; diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RetrofitClientCodegen.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RetrofitClientCodegen.java new file mode 100644 index 00000000000..6f80f8a5c5e --- /dev/null +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/RetrofitClientCodegen.java @@ -0,0 +1,190 @@ +package com.wordnik.swagger.codegen.languages; + +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.Operation; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; +import java.io.File; + +public class RetrofitClientCodegen extends DefaultCodegen implements CodegenConfig { + protected String invokerPackage = "io.swagger.client"; + protected String groupId = "io.swagger"; + protected String artifactId = "swagger-java-client"; + protected String artifactVersion = "1.0.0"; + protected String sourceFolder = "src/main/java"; + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "retrofit"; + } + + public String getHelp() { + return "Generates a Retrofit client library."; + } + + public RetrofitClientCodegen() { + super(); + outputFolder = "generated-code/java"; + modelTemplateFiles.put("model.mustache", ".java"); + apiTemplateFiles.put("api.mustache", ".java"); + templateDir = "retrofit"; + apiPackage = "io.swagger.client.api"; + modelPackage = "io.swagger.client.model"; + + reservedWords = new HashSet ( + Arrays.asList( + "abstract", "continue", "for", "new", "switch", "assert", + "default", "if", "package", "synchronized", "boolean", "do", "goto", "private", + "this", "break", "double", "implements", "protected", "throw", "byte", "else", + "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", + "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", + "void", "class", "finally", "long", "strictfp", "volatile", "const", "float", + "native", "super", "while") + ); + + 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("service.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ServiceGenerator.java")); + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "String", + "boolean", + "Boolean", + "Double", + "Integer", + "Long", + "Float", + "Object") + ); + instantiationTypes.put("array", "ArrayList"); + instantiationTypes.put("map", "HashMap"); + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar); + } + + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar); + } + + @Override + public String toVarName(String name) { + // replace - with _ e.g. created-at => created_at + name = name.replaceAll("-", "_"); + + // if it's all uppper case, do nothing + if (name.matches("^[A-Z_]*$")) + return name; + + // camelize (lower first character) the variable name + // pet_id => petId + name = camelize(name, true); + + // for reserved word or word starting with number, append _ + if(reservedWords.contains(name) || name.matches("^\\d.*")) + name = escapeReservedWord(name); + + return name; + } + + @Override + public String toParamName(String name) { + // should be the same as variable name + return toVarName(name); + } + + @Override + public String toModelName(String name) { + // model name cannot use reserved keyword, e.g. return + if(reservedWords.contains(name)) + throw new RuntimeException(name + " (reserved word) cannot be used as a model name"); + + // camelize the model name + // phone_number => PhoneNumber + return camelize(name); + } + + @Override + public String toModelFilename(String name) { + // should be the same as the model name + return toModelName(name); + } + + + @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) + ""; + } + 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 toOperationId(String operationId) { + // method name cannot use reserved keyword, e.g. return + if(reservedWords.contains(operationId)) + throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); + + return camelize(operationId, true); + } + + public Map postProcessOperations(Map objs) { + Map operations = (Map)objs.get("operations"); + if(operations != null) { + List ops = (List) operations.get("operation"); + for(CodegenOperation operation : ops) { + if (operation.hasConsumes == Boolean.TRUE) { + Map firstType = operation.consumes.get(0); + if (firstType != null) { + if ("multipart/form-data".equals(firstType.get("mediaType"))) { + operation.isMultipart = Boolean.TRUE; + } + } + } + if(operation.returnType == null) { + operation.returnType = "Void"; + } + } + } + return objs; + } +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig index 73dbeae62ef..4dec8a51df5 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/com.wordnik.swagger.codegen.CodegenConfig @@ -10,6 +10,7 @@ com.wordnik.swagger.codegen.languages.PhpClientCodegen com.wordnik.swagger.codegen.languages.PythonClientCodegen com.wordnik.swagger.codegen.languages.Python3ClientCodegen com.wordnik.swagger.codegen.languages.Qt5CPPGenerator +com.wordnik.swagger.codegen.languages.RetrofitClientCodegen com.wordnik.swagger.codegen.languages.RubyClientCodegen com.wordnik.swagger.codegen.languages.ScalaClientCodegen com.wordnik.swagger.codegen.languages.ScalatraServerCodegen diff --git a/modules/swagger-codegen/src/main/resources/retrofit/api.mustache b/modules/swagger-codegen/src/main/resources/retrofit/api.mustache new file mode 100644 index 00000000000..a916f363ff5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/api.mustache @@ -0,0 +1,29 @@ +package {{package}}; + +import {{modelPackage}}.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +{{#imports}}import {{import}}; +{{/imports}} + +{{#operations}} +public interface {{classname}} { + {{#operation}} + /** + * {{summary}} + * {{notes}} +{{#allParams}} * @param {{paramName}} {{description}} +{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} + */ + {{#formParams}}{{#-first}} + {{#isMultipart}}@Multipart{{/isMultipart}}{{^isMultipart}}@FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}} + @{{httpMethod}}("{{path}}") + {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{nickname}}({{^allParams}});{{/allParams}} + {{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}} + );{{/hasMore}}{{/allParams}} + {{/operation}} +} +{{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/retrofit/bodyParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/bodyParams.mustache new file mode 100644 index 00000000000..f8788583db5 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/bodyParams.mustache @@ -0,0 +1 @@ +{{#isBodyParam}}@Body {{{dataType}}} {{paramName}}{{/isBodyParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/formParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/formParams.mustache new file mode 100644 index 00000000000..9853bc0bf11 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/formParams.mustache @@ -0,0 +1 @@ +{{#isFormParam}}{{#notFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") {{{dataType}}} {{paramName}}{{/notFile}}{{#isFile}}{{#isMultipart}}@Part{{/isMultipart}}{{^isMultipart}}@Field{{/isMultipart}}("{{paramName}}") TypedFile {{paramName}}{{/isFile}}{{/isFormParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/headerParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/headerParams.mustache new file mode 100644 index 00000000000..29206e1546b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/headerParams.mustache @@ -0,0 +1 @@ +{{#isHeaderParam}}@Header("{{baseName}}") {{{dataType}}} {{paramName}}{{/isHeaderParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/model.mustache b/modules/swagger-codegen/src/main/resources/retrofit/model.mustache new file mode 100644 index 00000000000..f4446d5a1ef --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/model.mustache @@ -0,0 +1,50 @@ +package {{package}}; + +{{#imports}}import {{import}}; +{{/imports}} + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; +{{#models}} + +{{#model}}{{#description}} +/** + * {{description}} + **/{{/description}} +@ApiModel(description = "{{{description}}}") +public class {{classname}} {{#parent}}extends {{{parent}}}{{/parent}} { + {{#vars}}{{#isEnum}} + public enum {{datatypeWithEnum}} { + {{#allowableValues}}{{#values}} {{.}}, {{/values}}{{/allowableValues}} + };{{/isEnum}} + + /**{{#description}} + * {{{description}}}{{/description}}{{#minimum}} + * minimum: {{minimum}}{{/minimum}}{{#maximum}} + * maximum: {{maximum}}{{/maximum}} + **/ + @ApiModelProperty({{#required}}required = {{required}}, {{/required}}value = "{{{description}}}") + @SerializedName("{{baseName}}"){{#isEnum}} + private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{^isEnum}} + private {{{datatype}}} {{name}} = {{{defaultValue}}};{{/isEnum}}{{/vars}} + + {{#vars}} + public {{{datatypeWithEnum}}} {{getter}}() { + return {{name}}; + } + public void {{setter}}({{{datatypeWithEnum}}} {{name}}) { + this.{{name}} = {{name}}; + } + {{/vars}} + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class {{classname}} {\n"); + {{#parent}}sb.append(" " + super.toString()).append("\n");{{/parent}} + {{#vars}}sb.append(" {{name}}: ").append({{name}}).append("\n"); + {{/vars}}sb.append("}\n"); + return sb.toString(); + } +} +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/retrofit/pathParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/pathParams.mustache new file mode 100644 index 00000000000..8a8bdc74c88 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/pathParams.mustache @@ -0,0 +1 @@ +{{#isPathParam}}@Path("{{baseName}}") {{{dataType}}} {{paramName}}{{/isPathParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/pom.mustache b/modules/swagger-codegen/src/main/resources/retrofit/pom.mustache new file mode 100644 index 00000000000..fd631871054 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/pom.mustache @@ -0,0 +1,143 @@ + + 4.0.0 + {{groupId}} + {{artifactId}} + jar + {{artifactId}} + {{artifactVersion}} + + scm:git:git@github.com:wordnik/swagger-mustache.git + scm:git:git@github.com:wordnik/swagger-codegen.git + https://github.com/wordnik/swagger-codegen + + + 2.2.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + com.wordnik + swagger-annotations + ${swagger-annotations-version} + + + com.google.code.gson + gson + ${gson-version} + compile + + + com.squareup.retrofit + retrofit + ${retrofit-version} + compile + + + + + junit + junit + ${junit-version} + test + + + + 1.5.3-M1 + 2.3.1 + 1.9.0 + 1.0.0 + 4.12 + + diff --git a/modules/swagger-codegen/src/main/resources/retrofit/queryParams.mustache b/modules/swagger-codegen/src/main/resources/retrofit/queryParams.mustache new file mode 100644 index 00000000000..e0a58533e5f --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/queryParams.mustache @@ -0,0 +1 @@ +{{#isQueryParam}}@Query("{{baseName}}") {{{dataType}}} {{paramName}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/retrofit/service.mustache b/modules/swagger-codegen/src/main/resources/retrofit/service.mustache new file mode 100644 index 00000000000..218a9304071 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/retrofit/service.mustache @@ -0,0 +1,23 @@ +package {{invokerPackage}}; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import retrofit.RestAdapter; +import retrofit.converter.GsonConverter; + +public class ServiceGenerator { + // No need to instantiate this class. + private ServiceGenerator() { } + + public static S createService(Class serviceClass) { + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + .create(); + RestAdapter adapter = new RestAdapter.Builder() + .setEndpoint("{{basePath}}") + .setConverter(new GsonConverter(gson)) + .build(); + + return adapter.create(serviceClass); + } +} diff --git a/pom.xml b/pom.xml index 6fbb36464f8..c8d223cfb2c 100644 --- a/pom.xml +++ b/pom.xml @@ -350,6 +350,18 @@ samples/client/petstore/ruby + + retrofit-client + + + env + java + + + + samples/client/petstore/retrofit + + spring-mvc diff --git a/samples/client/petstore/android-java/src/main/java/AndroidManifest.xml b/samples/client/petstore/android-java/src/main/java/AndroidManifest.xml new file mode 100644 index 00000000000..3042699fd86 --- /dev/null +++ b/samples/client/petstore/android-java/src/main/java/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + diff --git a/samples/client/petstore/retrofit/pom.xml b/samples/client/petstore/retrofit/pom.xml new file mode 100644 index 00000000000..4a95855cac9 --- /dev/null +++ b/samples/client/petstore/retrofit/pom.xml @@ -0,0 +1,143 @@ + + 4.0.0 + io.swagger + swagger-java-client + jar + swagger-java-client + 1.0.0 + + scm:git:git@github.com:wordnik/swagger-mustache.git + scm:git:git@github.com:wordnik/swagger-codegen.git + https://github.com/wordnik/swagger-codegen + + + 2.2.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + + loggerPath + conf/log4j.properties + + + -Xms512m -Xmx1500m + methods + pertest + + + + maven-dependency-plugin + + + package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + jar + test-jar + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add_sources + generate-sources + + add-source + + + + src/main/java + + + + + add_test_sources + generate-test-sources + + add-test-source + + + + src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + com.wordnik + swagger-annotations + ${swagger-annotations-version} + + + com.google.code.gson + gson + ${gson-version} + compile + + + com.squareup.retrofit + retrofit + ${retrofit-version} + compile + + + + + junit + junit + ${junit-version} + test + + + + 1.5.3-M1 + 2.3.1 + 1.9.0 + 1.0.0 + 4.12 + + diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/ServiceGenerator.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/ServiceGenerator.java new file mode 100644 index 00000000000..e443c984fd0 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/ServiceGenerator.java @@ -0,0 +1,23 @@ +package io.swagger.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import retrofit.RestAdapter; +import retrofit.converter.GsonConverter; + +public class ServiceGenerator { + // No need to instantiate this class. + private ServiceGenerator() { } + + public static S createService(Class serviceClass) { + Gson gson = new GsonBuilder() + .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") + .create(); + RestAdapter adapter = new RestAdapter.Builder() + .setEndpoint("http://petstore.swagger.io/v2") + .setConverter(new GsonConverter(gson)) + .build(); + + return adapter.create(serviceClass); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java new file mode 100644 index 00000000000..3d1b0893b61 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/PetApi.java @@ -0,0 +1,117 @@ +package io.swagger.client.api; + +import io.swagger.client.model.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +import io.swagger.client.model.Pet; +import java.io.File; + +public interface PetApi { + + /** + * Update an existing pet + * + * @param body Pet object that needs to be added to the store + * @return Void + */ + + @PUT("/pet") + Void updatePet( + @Body Pet body + ); + + /** + * Add a new pet to the store + * + * @param body Pet object that needs to be added to the store + * @return Void + */ + + @POST("/pet") + Void addPet( + @Body Pet body + ); + + /** + * Finds Pets by status + * Multiple status values can be provided with comma seperated strings + * @param status Status values that need to be considered for filter + * @return List + */ + + @GET("/pet/findByStatus") + List findPetsByStatus( + @Query("status") List status + ); + + /** + * Finds Pets by tags + * Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + * @return List + */ + + @GET("/pet/findByTags") + List findPetsByTags( + @Query("tags") List tags + ); + + /** + * Find pet by ID + * Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + * @param petId ID of pet that needs to be fetched + * @return Pet + */ + + @GET("/pet/{petId}") + Pet getPetById( + @Path("petId") Long petId + ); + + /** + * Updates a pet in the store with form data + * + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet + * @param status Updated status of the pet + * @return Void + */ + + @FormUrlEncoded + @POST("/pet/{petId}") + Void updatePetWithForm( + @Path("petId") String petId,@Field("name") String name,@Field("status") String status + ); + + /** + * Deletes a pet + * + * @param apiKey + * @param petId Pet id to delete + * @return Void + */ + + @DELETE("/pet/{petId}") + Void deletePet( + @Header("api_key") String apiKey,@Path("petId") Long petId + ); + + /** + * uploads an image + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server + * @param file file to upload + * @return Void + */ + + @Multipart + @POST("/pet/{petId}/uploadImage") + Void uploadFile( + @Path("petId") Long petId,@Part("additionalMetadata") String additionalMetadata,@Part("file") TypedFile file + ); + +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/StoreApi.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/StoreApi.java new file mode 100644 index 00000000000..fcd47b4b735 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/StoreApi.java @@ -0,0 +1,60 @@ +package io.swagger.client.api; + +import io.swagger.client.model.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +import java.util.Map; +import io.swagger.client.model.Order; + +public interface StoreApi { + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + * @return Map + */ + + @GET("/store/inventory") + Map getInventory(); + + + /** + * Place an order for a pet + * + * @param body order placed for purchasing the pet + * @return Order + */ + + @POST("/store/order") + Order placeOrder( + @Body Order body + ); + + /** + * Find purchase order by ID + * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + * @param orderId ID of pet that needs to be fetched + * @return Order + */ + + @GET("/store/order/{orderId}") + Order getOrderById( + @Path("orderId") String orderId + ); + + /** + * Delete purchase order by ID + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @param orderId ID of the order that needs to be deleted + * @return Void + */ + + @DELETE("/store/order/{orderId}") + Void deleteOrder( + @Path("orderId") String orderId + ); + +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/UserApi.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/UserApi.java new file mode 100644 index 00000000000..4aa39c52e2c --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/api/UserApi.java @@ -0,0 +1,110 @@ +package io.swagger.client.api; + +import io.swagger.client.model.*; + +import retrofit.http.*; +import retrofit.mime.*; +import java.util.*; + +import io.swagger.client.model.User; +import java.util.*; + +public interface UserApi { + + /** + * Create user + * This can only be done by the logged in user. + * @param body Created user object + * @return Void + */ + + @POST("/user") + Void createUser( + @Body User body + ); + + /** + * Creates list of users with given input array + * + * @param body List of user object + * @return Void + */ + + @POST("/user/createWithArray") + Void createUsersWithArrayInput( + @Body List body + ); + + /** + * Creates list of users with given input array + * + * @param body List of user object + * @return Void + */ + + @POST("/user/createWithList") + Void createUsersWithListInput( + @Body List body + ); + + /** + * Logs user into the system + * + * @param username The user name for login + * @param password The password for login in clear text + * @return String + */ + + @GET("/user/login") + String loginUser( + @Query("username") String username,@Query("password") String password + ); + + /** + * Logs out current logged in user session + * + * @return Void + */ + + @GET("/user/logout") + Void logoutUser(); + + + /** + * Get user by user name + * + * @param username The name that needs to be fetched. Use user1 for testing. + * @return User + */ + + @GET("/user/{username}") + User getUserByName( + @Path("username") String username + ); + + /** + * Updated user + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param body Updated user object + * @return Void + */ + + @PUT("/user/{username}") + Void updateUser( + @Path("username") String username,@Body User body + ); + + /** + * Delete user + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + * @return Void + */ + + @DELETE("/user/{username}") + Void deleteUser( + @Path("username") String username + ); + +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Category.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Category.java new file mode 100644 index 00000000000..8ba10d629dc --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Category.java @@ -0,0 +1,49 @@ +package io.swagger.client.model; + + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Category { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("name") + private String name = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Category {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" name: ").append(name).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Order.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Order.java new file mode 100644 index 00000000000..d7d0b2d9282 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Order.java @@ -0,0 +1,110 @@ +package io.swagger.client.model; + +import java.util.Date; + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Order { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("petId") + private Long petId = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("quantity") + private Integer quantity = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("shipDate") + private Date shipDate = null; + public enum StatusEnum { + placed, approved, delivered, + }; + + /** + * Order Status + **/ + @ApiModelProperty(value = "Order Status") + @SerializedName("status") + private StatusEnum status = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("complete") + private Boolean complete = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public Long getPetId() { + return petId; + } + public void setPetId(Long petId) { + this.petId = petId; + } + + public Integer getQuantity() { + return quantity; + } + public void setQuantity(Integer quantity) { + this.quantity = quantity; + } + + public Date getShipDate() { + return shipDate; + } + public void setShipDate(Date shipDate) { + this.shipDate = shipDate; + } + + public StatusEnum getStatus() { + return status; + } + public void setStatus(StatusEnum status) { + this.status = status; + } + + public Boolean getComplete() { + return complete; + } + public void setComplete(Boolean complete) { + this.complete = complete; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Order {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" petId: ").append(petId).append("\n"); + sb.append(" quantity: ").append(quantity).append("\n"); + sb.append(" shipDate: ").append(shipDate).append("\n"); + sb.append(" status: ").append(status).append("\n"); + sb.append(" complete: ").append(complete).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Pet.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Pet.java new file mode 100644 index 00000000000..66a02367c90 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Pet.java @@ -0,0 +1,112 @@ +package io.swagger.client.model; + +import io.swagger.client.model.Category; +import java.util.*; +import io.swagger.client.model.Tag; + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Pet { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("category") + private Category category = null; + + /** + **/ + @ApiModelProperty(required = true, value = "") + @SerializedName("name") + private String name = null; + + /** + **/ + @ApiModelProperty(required = true, value = "") + @SerializedName("photoUrls") + private List photoUrls = new ArrayList() ; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("tags") + private List tags = new ArrayList() ; + public enum StatusEnum { + available, pending, sold, + }; + + /** + * pet status in the store + **/ + @ApiModelProperty(value = "pet status in the store") + @SerializedName("status") + private StatusEnum status = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public Category getCategory() { + return category; + } + public void setCategory(Category category) { + this.category = category; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public List getPhotoUrls() { + return photoUrls; + } + public void setPhotoUrls(List photoUrls) { + this.photoUrls = photoUrls; + } + + public List getTags() { + return tags; + } + public void setTags(List tags) { + this.tags = tags; + } + + public StatusEnum getStatus() { + return status; + } + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Pet {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" category: ").append(category).append("\n"); + sb.append(" name: ").append(name).append("\n"); + sb.append(" photoUrls: ").append(photoUrls).append("\n"); + sb.append(" tags: ").append(tags).append("\n"); + sb.append(" status: ").append(status).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Tag.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Tag.java new file mode 100644 index 00000000000..e6ddd4c92cd --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/Tag.java @@ -0,0 +1,49 @@ +package io.swagger.client.model; + + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class Tag { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("name") + private String name = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Tag {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" name: ").append(name).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/User.java b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/User.java new file mode 100644 index 00000000000..f42f77b9773 --- /dev/null +++ b/samples/client/petstore/retrofit/src/main/java/io/swagger/client/model/User.java @@ -0,0 +1,134 @@ +package io.swagger.client.model; + + +import com.wordnik.swagger.annotations.*; +import com.google.gson.annotations.SerializedName; + + +@ApiModel(description = "") +public class User { + + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("id") + private Long id = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("username") + private String username = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("firstName") + private String firstName = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("lastName") + private String lastName = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("email") + private String email = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("password") + private String password = null; + + /** + **/ + @ApiModelProperty(value = "") + @SerializedName("phone") + private String phone = null; + + /** + * User Status + **/ + @ApiModelProperty(value = "User Status") + @SerializedName("userStatus") + private Integer userStatus = null; + + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + + public String getPhone() { + return phone; + } + public void setPhone(String phone) { + this.phone = phone; + } + + public Integer getUserStatus() { + return userStatus; + } + public void setUserStatus(Integer userStatus) { + this.userStatus = userStatus; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class User {\n"); + + sb.append(" id: ").append(id).append("\n"); + sb.append(" username: ").append(username).append("\n"); + sb.append(" firstName: ").append(firstName).append("\n"); + sb.append(" lastName: ").append(lastName).append("\n"); + sb.append(" email: ").append(email).append("\n"); + sb.append(" password: ").append(password).append("\n"); + sb.append(" phone: ").append(phone).append("\n"); + sb.append(" userStatus: ").append(userStatus).append("\n"); + sb.append("}\n"); + return sb.toString(); + } +} diff --git a/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/PetApiTest.java b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/PetApiTest.java new file mode 100644 index 00000000000..c588a04adcc --- /dev/null +++ b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/PetApiTest.java @@ -0,0 +1,158 @@ +package io.swagger.petstore.test; + +import io.swagger.client.ServiceGenerator; +import io.swagger.client.api.*; +import io.swagger.client.model.*; + +import retrofit.RetrofitError; +import retrofit.mime.TypedFile; + +import java.util.*; +import java.io.*; + +import static org.junit.Assert.*; +import org.junit.*; + +public class PetApiTest { + PetApi api = null; + + @Before + public void setup() { + api = ServiceGenerator.createService(PetApi.class); + } + + @Test + public void testCreateAndGetPet() throws Exception { + Pet pet = createRandomPet(); + api.addPet(pet); + + Pet fetched = api.getPetById(pet.getId()); + assertNotNull(fetched); + assertEquals(pet.getId(), fetched.getId()); + assertNotNull(fetched.getCategory()); + assertEquals(fetched.getCategory().getName(), pet.getCategory().getName()); + } + + @Test + public void testUpdatePet() throws Exception { + Pet pet = createRandomPet(); + pet.setName("programmer"); + + api.updatePet(pet); + + Pet fetched = api.getPetById(pet.getId()); + assertNotNull(fetched); + assertEquals(pet.getId(), fetched.getId()); + assertNotNull(fetched.getCategory()); + assertEquals(fetched.getCategory().getName(), pet.getCategory().getName()); + } + + @Test + public void testFindPetsByStatus() throws Exception { + Pet pet = createRandomPet(); + pet.setName("programmer"); + pet.setStatus(Pet.StatusEnum.available); + + api.updatePet(pet); + + List pets = api.findPetsByStatus(Arrays.asList(new String[]{"available"})); + assertNotNull(pets); + + boolean found = false; + for(Pet fetched : pets) { + if(fetched.getId().equals(pet.getId())) { + found = true; + break; + } + } + + assertTrue(found); + } + + @Test + public void testFindPetsByTags() throws Exception { + Pet pet = createRandomPet(); + pet.setName("monster"); + pet.setStatus(Pet.StatusEnum.available); + + List tags = new ArrayList(); + Tag tag1 = new Tag(); + tag1.setName("friendly"); + tags.add(tag1); + pet.setTags(tags); + + api.updatePet(pet); + + List pets = api.findPetsByTags(Arrays.asList(new String[]{"friendly"})); + assertNotNull(pets); + + boolean found = false; + for(Pet fetched : pets) { + if(fetched.getId().equals(pet.getId())) { + found = true; + break; + } + } + assertTrue(found); + } + + @Test + public void testUpdatePetWithForm() throws Exception { + Pet pet = createRandomPet(); + pet.setName("frank"); + api.addPet(pet); + + Pet fetched = api.getPetById(pet.getId()); + + api.updatePetWithForm(String.valueOf(fetched.getId()), "furt", null); + Pet updated = api.getPetById(fetched.getId()); + + assertEquals(updated.getName(), fetched.getName()); + } + + @Test + public void testDeletePet() throws Exception { + Pet pet = createRandomPet(); + api.addPet(pet); + + Pet fetched = api.getPetById(pet.getId()); + api.deletePet(null, fetched.getId()); + + try { + fetched = api.getPetById(fetched.getId()); + fail("expected an error"); + } + catch (RetrofitError e) { + assertEquals(404, e.getResponse().getStatus()); + } + } + + @Test + public void testUploadFile() throws Exception { + Pet pet = createRandomPet(); + api.addPet(pet); + + File file = new File("hello.txt"); + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write("Hello world!"); + writer.close(); + + api.uploadFile(pet.getId(), "a test file", new TypedFile("text/plain", file)); + } + + private Pet createRandomPet() { + Pet pet = new Pet(); + pet.setId(System.currentTimeMillis()); + pet.setName("gorilla"); + + Category category = new Category(); + category.setName("really-happy"); + + pet.setCategory(category); + pet.setStatus(Pet.StatusEnum.available); + List photos = Arrays.asList(new String[]{"http://foo.bar.com/1", "http://foo.bar.com/2"}); + pet.setPhotoUrls(photos); + + return pet; + } +} \ No newline at end of file diff --git a/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/StoreApiTest.java b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/StoreApiTest.java new file mode 100644 index 00000000000..733b597fefc --- /dev/null +++ b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/StoreApiTest.java @@ -0,0 +1,70 @@ +package io.swagger.petstore.test; + +import io.swagger.client.ServiceGenerator; +import io.swagger.client.api.*; +import io.swagger.client.model.*; + +import retrofit.RetrofitError; + +import java.util.*; +import java.io.*; + +import static org.junit.Assert.*; +import org.junit.*; + +public class StoreApiTest { + StoreApi api = null; + + @Before + public void setup() { + api = ServiceGenerator.createService(StoreApi.class); + } + + @Test + public void testGetInventory() throws Exception { + Map inventory = api.getInventory(); + assertTrue(inventory.keySet().size() > 0); + } + + @Test + public void testPlaceOrder() throws Exception { + Order order = createOrder(); + api.placeOrder(order); + + Order fetched = api.getOrderById(String.valueOf(order.getId())); + assertEquals(order.getId(), fetched.getId()); + assertEquals(order.getPetId(), fetched.getPetId()); + assertEquals(order.getQuantity(), fetched.getQuantity()); + } + + @Test + public void testDeleteOrder() throws Exception { + Order order = createOrder(); + api.placeOrder(order); + + Order fetched = api.getOrderById(String.valueOf(order.getId())); + assertEquals(fetched.getId(), order.getId()); + + api.deleteOrder(String.valueOf(order.getId())); + + try { + api.getOrderById(String.valueOf(order.getId())); + // fail("expected an error"); + } + catch (RetrofitError e) { + // ok + } + } + + private Order createOrder() { + Order order = new Order(); + order.setId(new Long(System.currentTimeMillis())); + order.setPetId(new Long(200)); + order.setQuantity(new Integer(13)); + order.setShipDate(new java.util.Date()); + order.setStatus(Order.StatusEnum.placed); + order.setComplete(true); + + return order; + } +} \ No newline at end of file diff --git a/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/UserApiTest.java b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/UserApiTest.java new file mode 100644 index 00000000000..c7748bc492d --- /dev/null +++ b/samples/client/petstore/retrofit/src/test/java/io/swagger/petstore/test/UserApiTest.java @@ -0,0 +1,84 @@ +package io.swagger.petstore.test; + +import io.swagger.client.ServiceGenerator; +import io.swagger.client.api.*; +import io.swagger.client.model.*; + +import java.util.*; +import java.io.*; + +import static org.junit.Assert.*; +import org.junit.*; + +public class UserApiTest { + UserApi api = null; + + @Before + public void setup() { + api = ServiceGenerator.createService(UserApi.class); + } + + @Test + public void testCreateUser() throws Exception { + User user = createUser(); + + api.createUser(user); + + User fetched = api.getUserByName(user.getUsername()); + assertEquals(user.getId(), fetched.getId()); + } + + @Test + public void testCreateUsersWithArray() throws Exception { + User user1 = createUser(); + user1.setUsername("abc123"); + User user2 = createUser(); + user2.setUsername("123abc"); + + api.createUsersWithArrayInput(Arrays.asList(new User[]{user1, user2})); + + User fetched = api.getUserByName(user1.getUsername()); + assertEquals(user1.getId(), fetched.getId()); + } + + @Test + public void testCreateUsersWithList() throws Exception { + User user1 = createUser(); + user1.setUsername("abc123"); + User user2 = createUser(); + user2.setUsername("123abc"); + + api.createUsersWithListInput(Arrays.asList(new User[]{user1, user2})); + + User fetched = api.getUserByName(user1.getUsername()); + assertEquals(user1.getId(), fetched.getId()); + } + + @Test + public void testLoginUser() throws Exception { + User user = createUser(); + api.createUser(user); + + String token = api.loginUser(user.getUsername(), user.getPassword()); + assertTrue(token.startsWith("logged in user session:")); + } + + @Test + public void logoutUser() throws Exception { + api.logoutUser(); + } + + private User createUser() { + User user = new User(); + user.setId(System.currentTimeMillis()); + user.setUsername("fred"); + user.setFirstName("Fred"); + user.setLastName("Meyer"); + user.setEmail("fred@fredmeyer.com"); + user.setPassword("xxXXxx"); + user.setPhone("408-867-5309"); + user.setUserStatus(123); + + return user; + } +} \ No newline at end of file