added java sample

This commit is contained in:
Tony Tam 2013-04-03 00:19:21 -07:00
parent 98f1941b30
commit 958206c469
32 changed files with 1574 additions and 0 deletions

View File

@ -0,0 +1,134 @@
/**
* Copyright 2012 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.
*/
import com.wordnik.swagger.codegen.BasicJavaGenerator
import scala.collection.mutable.{ HashMap, ListBuffer }
object JavaJaxRSServerGenerator extends BasicJavaGenerator {
def main(args: Array[String]) = generateClient(args)
override def templateDir = "samples/server-generator/java-jaxrs/templates"
val outputFolder = "samples/server-generator/java-jaxrs/output"
// where to write generated code
override def destinationDir = outputFolder + "/src/main/java"
override def modelPackage = Some("com.wordnik.client.model")
// template used for apis
apiTemplateFiles ++= Map("api.mustache" -> ".java")
modelTemplateFiles ++= Map("model.mustache" -> ".java")
override def apiPackage = Some("com.wordnik.api")
// supporting classes
override def supportingFiles = List(
("README.mustache", outputFolder, "README.md"),
("ApiResponse.mustache", destinationDir + "/" + apiPackage.get.replaceAll("\\.", "/"), "ApiResponse.java"),
("JacksonJsonProvider.mustache", destinationDir + "/" + apiPackage.get.replaceAll("\\.", "/"), "JacksonJsonProvider.java"),
("ApiException.mustache", destinationDir + "/" + apiPackage.get.replaceAll("\\.", "/"), "ApiException.java"),
("NotFoundException.mustache", destinationDir + "/" + apiPackage.get.replaceAll("\\.", "/"), "NotFoundException.java"),
("pom.xml", outputFolder, "pom.xml"),
("web.mustache", outputFolder + "/src/main/webapp/WEB-INF", "web.xml")
)
override def processApiMap(m: Map[String, AnyRef]): Map[String, AnyRef] = {
val mutable = scala.collection.mutable.Map() ++ m
mutable.map(k => {
k._1 match {
case "allParams" => {
val paramList = k._2.asInstanceOf[List[_]]
paramList.foreach(param => {
val map = param.asInstanceOf[scala.collection.mutable.HashMap[String, AnyRef]]
if(map.contains("dataType")){
val dataType = map("dataType")
map += "dataType" -> dataType.toString.replaceAll("Array\\[","List[")
}
if(map.contains("required")) {
if(map("required") == "false") map += "notRequired" -> "true"
}
if(map.contains("defaultValue")) {
// unquote default value
val defaultValue = {
map("defaultValue") match {
case Some(d) => {
val str = d.toString
if(str.startsWith("\"") && str.endsWith("\""))
Some(str.substring(1, str.length-1))
else Some(d)
}
case None => None
}
}
map += "defaultValue" -> defaultValue
}
if(map.contains("allowableValues")) {
val allowableValues = map("allowableValues")
val quote = map("swaggerDataType") match {
case "string" => "\""
case _ => ""
}
val pattern = "([A-Z]*)\\[(.*)\\]".r
val str = allowableValues match {
case pattern(valueType, values) => {
valueType match {
case "LIST" => {
val l = values.split(",").toList
Some("AllowableValues(" + l.mkString(quote, quote + "," + quote, quote + ")"))
}
case "RANGE" => {
val r = values.split(",")
Some("AllowableValues(Range(" + r(0) + "," + r(1) + ", 1))")
}
}
}
case _ => None
}
str match {
case Some(s) => map += "allowableValues" -> s
case _ =>
}
}
})
}
case "path" => {
val path = {
val arr = k._2.toString.split("/")
if (arr.length >= 2) {
mutable += "basePart" -> (arr.slice(2, arr.length).mkString("", "/", ""))
"/" + arr.slice(2, arr.length).mkString("", "/", "")
} else
k._2.toString
}
// rip out the root path
mutable += "path" -> path
}
case "returnType" => {
k._2 match {
case Some(returnType) =>
case None => mutable += "returnType" -> "void"
}
}
case _ =>
}
})
mutable.toMap
}
}

View File

@ -0,0 +1,80 @@
# Swagger generated server
## Overview
Using the swagger-codegen, you can not only generate clients but servers as well! The same spec can be used to drive your
development both ways. This is an example of generating a server for `JAX-RS`.
### Prerequisites
You need the following installed and available in your $PATH:
<li>Maven 3</li>
### Generating a server
You first need to build the `swagger-codegen` project--this is done by running this command at the root of the swagger-codegen project:
```
sbt assembly
```
You can now generate a server from any valid[**](https://github.com/wordnik/swagger-codegen/blob/master/README.md#validating-your-swagger-spec) swagger spec:
```
./bin/runscala.sh samples/server-generator/java-jaxrs/JavaJaxRSServerGenerator.scala http://petstore.swagger.wordnik.com/api/api-docs.json special-key
```
After executing this script, you will have an output directory with the server-generated files:
```
$ cd samples/server-generator/java-jaxrs/output
$ find .
./pom.xml
./README.md
./src
./src/main
./src/main/java
./src/main/java/com
./src/main/java/com/wordnik
./src/main/java/com/wordnik/api
./src/main/java/com/wordnik/api/ApiException.java
./src/main/java/com/wordnik/api/ApiResponse.java
./src/main/java/com/wordnik/api/JacksonJsonProvider.java
./src/main/java/com/wordnik/api/NotFoundException.java
./src/main/java/com/wordnik/api/PetApi.java
./src/main/java/com/wordnik/api/StoreApi.java
./src/main/java/com/wordnik/api/UserApi.java
./src/main/java/com/wordnik/client
./src/main/java/com/wordnik/client/model
./src/main/java/com/wordnik/client/model/Category.java
./src/main/java/com/wordnik/client/model/Order.java
./src/main/java/com/wordnik/client/model/Pet.java
./src/main/java/com/wordnik/client/model/Tag.java
./src/main/java/com/wordnik/client/model/User.java
./src/main/webapp
./src/main/webapp/WEB-INF
./src/main/webapp/WEB-INF/web.xml
```
To run the server, cd to the `samples/server-generator/java-jaxrs/output` folder and run:
```
mvn jetty:run
```
You can now load the swagger-ui against `http://localhost:8002/api/api-docs.json`. Of course this isn't a fully
runnable server! You have to add the logic in the **/api/*.java files. But that's the easy part.
### Making it your own
Running the sample is easy, but how about making your own server? Easy! Just modify the `samples/server-generator/java-jaxrs/JavaJaxRSServerGenerator.scala` file.
Don't like the templates? Don't worry, we're not offended! They're [mustache](http://mustache.github.com/) templates and are easy to modify.
Take a look at the sample templates here:
<li> - Generator for your api classes: [api.mustache](https://github.com/wordnik/swagger-codegen/blob/master/samples/server-generator/java-jaxrs/templates/api.mustache)
<li> - Generator for your models: [model.mustache](https://github.com/wordnik/swagger-codegen/blob/master/samples/server-generator/java-jaxrs/templates/model.mustache)
<li> - Your web.xml: [web.mustache](https://github.com/wordnik/swagger-codegen/blob/master/samples/server-generator/java-jaxrs/templates/web.mustache)
Sound easy? It is!

View File

@ -0,0 +1,10 @@
# Swagger generated server
## Overview
This server was generated by the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project. By using the
[swagger-spec](https://github.com/wordnik/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
is an example of building a swagger-enabled scalatra server.
This example uses the [scalatra](http://scalatra.org/) framework. To see how to make this your own, look here:
[README](https://github.com/wordnik/swagger-codegen/tree/master/samples/server-generator/scalatra)

View File

@ -0,0 +1,109 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wordnik</groupId>
<artifactId>swagger-java-jaxrs-petstore</artifactId>
<packaging>war</packaging>
<name>swagger-java-jaxrs-petstore</name>
<version>1.0.0-SNAPSHOT</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<configuration>
<webAppConfig>
<contextPath>/api</contextPath>
</webAppConfig>
<webAppSourceDirectory>target/${project.artifactId}-${project.version}</webAppSourceDirectory>
<webDefaultXml>${project.basedir}/conf/jetty/webdefault.xml</webDefaultXml>
<stopPort>8079</stopPort>
<stopKey>stopit</stopKey>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8002</port>
<maxIdleTime>60000</maxIdleTime>
<confidentialPort>8443</confidentialPort>
</connector>
</connectors>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.9.1</artifactId>
<version>${swagger-core-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.9.1</artifactId>
<version>${scala-test-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api-version}</version>
</dependency>
</dependencies>
<properties>
<swagger-core-version>1.2.1</swagger-core-version>
<jetty-version>7.6.0.v20120127</jetty-version>
<slf4j-version>1.6.3</slf4j-version>
<scala-test-version>1.6.1</scala-test-version>
<junit-version>4.8.1</junit-version>
<servlet-api-version>2.5</servlet-api-version>
</properties>
</project>

View File

@ -0,0 +1,10 @@
package com.wordnik.api;
public class ApiException extends Exception{
private int code;
public ApiException (int code, String msg) {
super(msg);
this.code = code;
}
}

View File

@ -0,0 +1,69 @@
package com.wordnik.api;
import javax.xml.bind.annotation.XmlTransient;
@javax.xml.bind.annotation.XmlRootElement
public class ApiResponse {
public static final int ERROR = 1;
public static final int WARNING = 2;
public static final int INFO = 3;
public static final int OK = 4;
public static final int TOO_BUSY = 5;
int code;
String type;
String message;
public ApiResponse(){}
public ApiResponse(int code, String message){
this.code = code;
switch(code){
case ERROR:
setType("error");
break;
case WARNING:
setType("warning");
break;
case INFO:
setType("info");
break;
case OK:
setType("ok");
break;
case TOO_BUSY:
setType("too busy");
break;
default:
setType("unknown");
break;
}
this.message = message;
}
@XmlTransient
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,38 @@
package com.wordnik.api;
import com.wordnik.swagger.core.util.JsonUtil;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonJsonProvider extends JacksonJaxbJsonProvider {
private static ObjectMapper commonMapper = null;
public JacksonJsonProvider() {
if(commonMapper == null){
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
commonMapper = mapper;
}
super.setMapper(commonMapper);
}
}

View File

@ -0,0 +1,10 @@
package com.wordnik.api;
public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {
super(code, msg);
this.code = code;
}
}

View File

@ -0,0 +1,87 @@
package com.wordnik.api;
import com.wordnik.swagger.annotations.*;
import com.wordnik.client.model.Pet;
import java.util.List;
import com.wordnik.api.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.*;
@Path("/pet.json")
@Api(value = "/pet", description = "the pet API")
@Produces({"application/json"})
public class PetApi {
@GET
@Path("/{petId}")
@ApiOperation(value = "Find pet by ID", notes = "Returns a pet based on ID", responseClass = "Pet")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response getPetById(
@ApiParam(value = "ID of pet that needs to be fetched"
,required=true)@PathParam("petId") String petId
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@POST
@Path("/")
@ApiOperation(value = "Add a new pet to the store", notes = "", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response addPet(
@ApiParam(value = "Pet object that needs to be added to the store"
,required=true) Pet body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@PUT
@Path("/")
@ApiOperation(value = "Update an existing pet", notes = "", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response updatePet(
@ApiParam(value = "Pet object that needs to be updated in the store"
,required=true) Pet body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@GET
@Path("/findByStatus")
@ApiOperation(value = "Finds Pets by status", notes = "Multiple status values can be provided with comma seperated strings", responseClass = "List<Pet>")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response findPetsByStatus(
@ApiParam(value = "Status values that need to be considered for filter"
,required=true, defaultValue="available")@QueryParam("status") String status
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@GET
@Path("/findByTags")
@ApiOperation(value = "Finds Pets by tags", notes = "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", responseClass = "List<Pet>")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response findPetsByTags(
@ApiParam(value = "Tags to filter by"
,required=true)@QueryParam("tags") String tags
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
}

View File

@ -0,0 +1,59 @@
package com.wordnik.api;
import com.wordnik.swagger.annotations.*;
import com.wordnik.client.model.Order;
import java.util.List;
import com.wordnik.api.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.*;
@Path("/store.json")
@Api(value = "/store", description = "the store API")
@Produces({"application/json"})
public class StoreApi {
@GET
@Path("/order/{orderId}")
@ApiOperation(value = "Find purchase order by ID", notes = "For valid response try integer IDs with value <= 5. Anything above 5 or nonintegers will generate API errors", responseClass = "Order")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response getOrderById(
@ApiParam(value = "ID of pet that needs to be fetched"
,required=true)@PathParam("orderId") String orderId
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@DELETE
@Path("/order/{orderId}")
@ApiOperation(value = "Delete purchase order by ID", notes = "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response deleteOrder(
@ApiParam(value = "ID of the order that needs to be deleted"
,required=true)@PathParam("orderId") String orderId
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@POST
@Path("/order")
@ApiOperation(value = "Place an order for a pet", notes = "", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response placeOrder(
@ApiParam(value = "order placed for purchasing the pet"
,required=true) Order body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
}

View File

@ -0,0 +1,131 @@
package com.wordnik.api;
import com.wordnik.swagger.annotations.*;
import com.wordnik.client.model.User;
import java.util.List;
import com.wordnik.api.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.*;
@Path("/user.json")
@Api(value = "/user", description = "the user API")
@Produces({"application/json"})
public class UserApi {
@POST
@Path("/createWithArray")
@ApiOperation(value = "Creates list of users with given input array", notes = "", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response createUsersWithArrayInput(
@ApiParam(value = "List of user object"
,required=true) List<User> body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@POST
@Path("/")
@ApiOperation(value = "Create user", notes = "This can only be done by the logged in user.", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response createUser(
@ApiParam(value = "Created user object"
,required=true) User body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@POST
@Path("/createWithList")
@ApiOperation(value = "Creates list of users with given list input", notes = "", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response createUsersWithListInput(
@ApiParam(value = "List of user object"
,required=true) List<User> body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@PUT
@Path("/{username}")
@ApiOperation(value = "Updated user", notes = "This can only be done by the logged in user.", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response updateUser(
@ApiParam(value = "name that need to be deleted"
,required=true)@PathParam("username") String username
,@ApiParam(value = "Updated user object"
,required=true) User body
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@DELETE
@Path("/{username}")
@ApiOperation(value = "Delete user", notes = "This can only be done by the logged in user.", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response deleteUser(
@ApiParam(value = "The name that needs to be deleted"
,required=true)@PathParam("username") String username
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@GET
@Path("/{username}")
@ApiOperation(value = "Get user by user name", notes = "", responseClass = "User")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response getUserByName(
@ApiParam(value = "The name that needs to be fetched. Use user1 for testing."
,required=true)@PathParam("username") String username
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@GET
@Path("/login")
@ApiOperation(value = "Logs user into the system", notes = "", responseClass = "String")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response loginUser(
@ApiParam(value = "The user name for login"
,required=true)@QueryParam("username") String username
,@ApiParam(value = "The password for login in clear text"
,required=true)@QueryParam("password") String password
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
@GET
@Path("/logout")
@ApiOperation(value = "Logs out current logged in user session", notes = "", responseClass = "void")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response logoutUser(
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
}

View File

@ -0,0 +1,30 @@
package com.wordnik.client.model;
public class Category {
private Long id = null;
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();
}
}

View File

@ -0,0 +1,59 @@
package com.wordnik.client.model;
import java.util.Date;
public class Order {
private Long id = null;
private Long petId = null;
/* Order Status */
private String status = null;
private Integer quantity = null;
private Date shipDate = 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 String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
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;
}
@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(" status: ").append(status).append("\n");
sb.append(" quantity: ").append(quantity).append("\n");
sb.append(" shipDate: ").append(shipDate).append("\n");
sb.append("}\n");
return sb.toString();
}
}

View File

@ -0,0 +1,70 @@
package com.wordnik.client.model;
import java.util.*;
import com.wordnik.client.model.Category;
import com.wordnik.client.model.Tag;
public class Pet {
private List<Tag> tags = new ArrayList<Tag>();
private Long id = null;
private Category category = null;
/* pet status in the store */
private String status = null;
private String name = null;
private List<String> photoUrls = new ArrayList<String>();
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
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 getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getPhotoUrls() {
return photoUrls;
}
public void setPhotoUrls(List<String> photoUrls) {
this.photoUrls = photoUrls;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Pet {\n");
sb.append(" tags: ").append(tags).append("\n");
sb.append(" id: ").append(id).append("\n");
sb.append(" category: ").append(category).append("\n");
sb.append(" status: ").append(status).append("\n");
sb.append(" name: ").append(name).append("\n");
sb.append(" photoUrls: ").append(photoUrls).append("\n");
sb.append("}\n");
return sb.toString();
}
}

View File

@ -0,0 +1,30 @@
package com.wordnik.client.model;
public class Tag {
private Long id = null;
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();
}
}

View File

@ -0,0 +1,85 @@
package com.wordnik.client.model;
public class User {
private Long id = null;
private String lastName = null;
private String phone = null;
private String username = null;
private String email = null;
/* User Status */
private Integer userStatus = null;
private String firstName = null;
private String password = null;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getUserStatus() {
return userStatus;
}
public void setUserStatus(Integer userStatus) {
this.userStatus = userStatus;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class User {\n");
sb.append(" id: ").append(id).append("\n");
sb.append(" lastName: ").append(lastName).append("\n");
sb.append(" phone: ").append(phone).append("\n");
sb.append(" username: ").append(username).append("\n");
sb.append(" email: ").append(email).append("\n");
sb.append(" userStatus: ").append(userStatus).append("\n");
sb.append(" firstName: ").append(firstName).append("\n");
sb.append(" password: ").append(password).append("\n");
sb.append("}\n");
return sb.toString();
}
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.wordnik.swagger.jaxrs.listing;com.wordnik.api</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.PostReplaceFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>api.version</param-name>
<param-value>0.1</param-value>
</init-param>
<init-param>
<param-name>swagger.version</param-name>
<param-value>1.1</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8002/api</param-value>
</init-param>
<init-param>
<param-name>swagger.security.filter</param-name>
<param-value>com.wordnik.swagger.sample.util.ApiAuthorizationFilterImpl</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- <filter>
<filter-name>ApiOriginFilter</filter-name>
<filter-class>com.wordnik.swagger.sample.util.ApiOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ApiOriginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
</web-app>

View File

@ -0,0 +1,9 @@
package {{apiPackage}};
public class ApiException extends Exception{
private int code;
public ApiException (int code, String msg) {
super(msg);
this.code = code;
}
}

View File

@ -0,0 +1,68 @@
package {{apiPackage}};
import javax.xml.bind.annotation.XmlTransient;
@javax.xml.bind.annotation.XmlRootElement
public class ApiResponse {
public static final int ERROR = 1;
public static final int WARNING = 2;
public static final int INFO = 3;
public static final int OK = 4;
public static final int TOO_BUSY = 5;
int code;
String type;
String message;
public ApiResponse(){}
public ApiResponse(int code, String message){
this.code = code;
switch(code){
case ERROR:
setType("error");
break;
case WARNING:
setType("warning");
break;
case INFO:
setType("info");
break;
case OK:
setType("ok");
break;
case TOO_BUSY:
setType("too busy");
break;
default:
setType("unknown");
break;
}
this.message = message;
}
@XmlTransient
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,20 @@
import {{apiPackage}}._
import com.wordnik.swagger.app.{ResourcesApp, SwaggerApp}
import javax.servlet.ServletContext
import org.scalatra.LifeCycle
class ScalatraBootstrap extends LifeCycle {
implicit val swagger = new SwaggerApp
override def init(context: ServletContext) {
try {
{{#apis}}
context mount (new {{className}}, "/{{name}}/*")
{{/apis}}
context mount (new ResourcesApp, "/api-docs/*")
} catch {
case e: Throwable => e.printStackTrace()
}
}
}

View File

@ -0,0 +1,38 @@
package {{apiPackage}};
import com.wordnik.swagger.core.util.JsonUtil;
import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.core.JsonGenerator.Feature;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonJsonProvider extends JacksonJaxbJsonProvider {
private static ObjectMapper commonMapper = null;
public JacksonJsonProvider() {
if(commonMapper == null){
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
commonMapper = mapper;
}
super.setMapper(commonMapper);
}
}

View File

@ -0,0 +1,32 @@
import org.eclipse.jetty.server.nio.SelectChannelConnector
import org.eclipse.jetty.server.{ Server }
import org.eclipse.jetty.server.handler.ContextHandlerCollection
import org.eclipse.jetty.webapp.WebAppContext
import org.eclipse.jetty.servlet.{ DefaultServlet, ServletContextHandler, ServletHolder }
object JettyMain {
def main(args: Array[String]) = {
val server: Server = new Server
println("starting jetty")
server setGracefulShutdown 5000
server setSendServerVersion false
server setSendDateHeader true
server setStopAtShutdown true
val connector = new SelectChannelConnector
connector setPort sys.env.get("PORT").map(_.toInt).getOrElse(8080)
connector setMaxIdleTime 90000
server addConnector connector
val webapp = sys.env.get("PUBLIC") getOrElse "webapp"
val webApp = new WebAppContext
webApp setContextPath "/"
webApp setResourceBase webapp
webApp setDescriptor (webapp+"/WEB-INF/web.xml");
server setHandler webApp
server.start()
}
}

View File

@ -0,0 +1,12 @@
package json
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.core.JsonGenerator.Feature
import com.fasterxml.jackson.databind._
object JsonUtil {
val mapper = new ObjectMapper()
mapper.registerModule(new DefaultScalaModule())
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
}

View File

@ -0,0 +1,9 @@
package {{apiPackage}};
public class NotFoundException extends ApiException {
private int code;
public NotFoundException (int code, String msg) {
super(code, msg);
this.code = code;
}
}

View File

@ -0,0 +1,10 @@
# Swagger generated server
## Overview
This server was generated by the [swagger-codegen](https://github.com/wordnik/swagger-codegen) project. By using the
[swagger-spec](https://github.com/wordnik/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
is an example of building a swagger-enabled scalatra server.
This example uses the [scalatra](http://scalatra.org/) framework. To see how to make this your own, look here:
[README](https://github.com/wordnik/swagger-codegen/tree/master/samples/server-generator/scalatra)

View File

@ -0,0 +1,26 @@
package com.wordnik.swagger.app
import com.wordnik.swagger.core.SwaggerSpec
import org.scalatra.swagger.{JacksonSwaggerBase, Swagger}
import org.scalatra.ScalatraServlet
import org.json4s.{DefaultFormats, Formats}
class ResourcesApp(implicit val swagger: Swagger) extends ScalatraServlet with JacksonSwaggerBase {
before() {
response.headers += ("Access-Control-Allow-Origin" -> "*")
}
protected def buildFullUrl(path: String) = if (path.startsWith("http")) path else {
val port = request.getServerPort
val h = request.getServerName
val prot = if (port == 443) "https" else "http"
val (proto, host) = if (port != 80 && port != 443) ("http", h+":"+port.toString) else (prot, h)
"%s://%s%s%s".format(
proto,
host,
request.getContextPath,
path)
}
}
class SwaggerApp extends Swagger(SwaggerSpec.version, "1")

View File

@ -0,0 +1,75 @@
package {{package}};
import com.wordnik.swagger.annotations.*;
{{#imports}}import {{import}};
{{/imports}}
import java.util.List;
import {{package}}.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.*;
@Path("/{{baseName}}.json")
@Api(value = "/{{baseName}}", description = "the {{baseName}} API")
@Produces({"application/json"})
public class {{className}} {
{{#operations}}
{{#operation}}
@{{httpMethod}}
@Path("{{path}}")
@ApiOperation(value = "{{{summary}}}", notes = "{{{notes}}}", responseClass = "{{{returnType}}}")
@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"),
@ApiError(code = 404, reason = "Pet not found") })
public Response {{nickname}}(
{{#allParams}}
{{#queryParameter}}
@ApiParam(value = "{{{description}}}"
{{#required}},required=true{{newline}}{{/required}}
{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{newline}}{{/allowableValues}}
{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{newline}}{{/defaultValue}}
)@QueryParam("{{paramName}}"){{newline}} {{{dataType}}} {{paramName}}
{{/queryParameter}}
{{#pathParameter}}
@ApiParam(value = "{{{description}}}"
{{#required}},required=true{{newline}}{{/required}}
{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{newline}}{{/allowableValues}}
{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{newline}}{{/defaultValue}}
)@PathParam("{{paramName}}"){{newline}} {{{dataType}}} {{paramName}}
{{/pathParameter}}
{{#headerParameter}}
@ApiParam(value = "{{{description}}}"
{{#required}},required=true{{newline}}{{/required}}
{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{newline}}{{/allowableValues}}
{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{newline}}{{/defaultValue}}
)@HeaderParam("{{paramName}}"){{newline}} {{{dataType}}} {{paramName}}
{{/headerParameter}}
{{#bodyParameter}}
@ApiParam(value = "{{{description}}}"
{{#required}},required=true{{newline}}{{/required}}
{{#allowableValues}}, allowableValues="{{{allowableValues}}}"{{newline}}{{/allowableValues}}
{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{newline}}{{/defaultValue}}
) {{{dataType}}} {{paramName}}
{{/bodyParameter}}
{{#hasMore}},{{/hasMore}}
{{/allParams}}
)
throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponse(ApiResponse.OK, "magic!")).build();
}
{{/operation}}
{{/operations}}
}

View File

@ -0,0 +1,38 @@
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
{{#models}}
{{#model}}
public class {{classname}} {
{{#vars}}
{{#description}}/* {{{description}}} */
{{/description}}
private {{{datatype}}} {{name}} = {{{defaultValue}}};
{{/vars}}
{{#vars}}
public {{{datatype}}} {{getter}}() {
return {{name}};
}
public void {{setter}}({{{datatype}}} {{name}}) {
this.{{name}} = {{name}};
}
{{/vars}}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class {{classname}} {\n");
{{#vars}}
sb.append(" {{name}}: ").append({{name}}).append("\n");
{{/vars}}
sb.append("}\n");
return sb.toString();
}
}
{{/model}}
{{/models}}

View File

@ -0,0 +1,109 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wordnik</groupId>
<artifactId>swagger-java-jaxrs-petstore</artifactId>
<packaging>war</packaging>
<name>swagger-java-jaxrs-petstore</name>
<version>1.0.0-SNAPSHOT</version>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-version}</version>
<configuration>
<webAppConfig>
<contextPath>/api</contextPath>
</webAppConfig>
<webAppSourceDirectory>target/${project.artifactId}-${project.version}</webAppSourceDirectory>
<webDefaultXml>${project.basedir}/conf/jetty/webdefault.xml</webDefaultXml>
<stopPort>8079</stopPort>
<stopKey>stopit</stopKey>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8002</port>
<maxIdleTime>60000</maxIdleTime>
<confidentialPort>8443</confidentialPort>
</connector>
</connectors>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.9.1</artifactId>
<version>${swagger-core-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.scalatest</groupId>
<artifactId>scalatest_2.9.1</artifactId>
<version>${scala-test-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api-version}</version>
</dependency>
</dependencies>
<properties>
<swagger-core-version>1.2.1</swagger-core-version>
<jetty-version>7.6.0.v20120127</jetty-version>
<slf4j-version>1.6.3</slf4j-version>
<scala-test-version>1.6.1</scala-test-version>
<junit-version>4.8.1</junit-version>
<servlet-api-version>2.5</servlet-api-version>
</properties>
</project>

View File

@ -0,0 +1 @@
sbt.version=0.12.0

View File

@ -0,0 +1,9 @@
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.4")
libraryDependencies <+= sbtVersion(v => v match {
case "0.11.0" => "com.github.siasia" %% "xsbt-web-plugin" % "0.11.0-0.2.8"
case "0.11.1" => "com.github.siasia" %% "xsbt-web-plugin" % "0.11.1-0.2.10"
case "0.11.2" => "com.github.siasia" %% "xsbt-web-plugin" % "0.11.2-0.2.11"
case "0.11.3" => "com.github.siasia" %% "xsbt-web-plugin" % "0.11.3-0.2.11.1"
case x if (x.startsWith("0.12")) => "com.github.siasia" %% "xsbt-web-plugin" % "0.12.0-0.2.11.1"
})

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:j2ee="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.wordnik.swagger.jaxrs.listing;{{apiPackage}}</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.PostReplaceFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>api.version</param-name>
<param-value>0.1</param-value>
</init-param>
<init-param>
<param-name>swagger.version</param-name>
<param-value>1.1</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8002/api</param-value>
</init-param>
<init-param>
<param-name>swagger.security.filter</param-name>
<param-value>com.wordnik.swagger.sample.util.ApiAuthorizationFilterImpl</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- <filter>
<filter-name>ApiOriginFilter</filter-name>
<filter-class>com.wordnik.swagger.sample.util.ApiOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ApiOriginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
</web-app>