Merge pull request #2 from fehguy/master

added scala library support
This commit is contained in:
fehguy 2011-09-05 07:14:16 -07:00
commit fd8d491a79
29 changed files with 1788 additions and 12 deletions

23
bin/generate-scala-lib.sh Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
if [ $# -ne 4 ]
then
echo "Error in $0 - Invalid Argument Count"
echo "Syntax: $0 location_of_service api_key package_name library_root"
exit
fi
echo "" > classpath.txt
for file in `ls lib`;
do echo -n 'lib/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
for file in `ls build`;
do echo -n 'build/' >> classpath.txt;
echo -n $file >> classpath.txt;
echo -n ':' >> classpath.txt;
done
export CLASSPATH=$(cat classpath.txt):conf/scala/templates
export JAVA_OPTS="${JAVA_OPTS} -Dproperty=Xmx2g"
scala $WORDNIK_OPTS $JAVA_CONFIG_OPTIONS $JAVA_OPTS -cp $CLASSPATH com.wordnik.swagger.codegen.config.scala.ScalaLibCodeGen "$@"

128
conf/scala/sample/build.xml Normal file
View File

@ -0,0 +1,128 @@
<?xml version="1.0"?>
<project name="swagger-sample-scala-lib" xmlns:ivy="antlib:org.apache.ivy.ant" default="build.all" basedir=".">
<property environment="env" />
<property name="version.identifier" value="1.0" />
<property name="artifact.ext" value="jar" />
<property name="organization" value="wordnik" />
<property name="module" value="${ant.project.name}" />
<!-- default dirs for the build -->
<mkdir dir="lib"/>
<mkdir dir="lib/ext"/>
<condition property="scala.home" value="${env.SCALA_HOME}">
<isset property="env.SCALA_HOME" />
</condition>
<path id="scala.classpath">
<fileset dir="${scala.home}/lib">
<include name="scala**.jar" />
</fileset>
</path>
<ivy:settings file="ivysettings.xml" />
<taskdef resource="scala/tools/ant/antlib.xml">
<classpath>
<fileset dir="lib">
<include name="scala**.jar" />
</fileset>
<fileset dir="${scala.home}/lib">
<include name="scala**.jar" />
</fileset>
</classpath>
</taskdef>
<!-- this is the output module -->
<property name="module" value="${ant.project.name}" />
<target name="build.all" depends="clean, resolve, fastcompile" description="builds the module (default target)" />
<target name="clean" description="cleans the project folder">
<mkdir dir="build" />
<echo message="deleting build files" />
<delete quiet="true">
<fileset dir="build">
<include name="*.jar" />
<include name="*.xml" />
</fileset>
</delete>
<delete dir="build/main" quiet="true" />
<delete dir="dist" quiet="true" />
<!-- libraries handled by ivy -->
<echo message="deleting libs handled by ivy" />
<delete>
<fileset dir="lib">
<include name="*.jar" />
<include name="*.zip" />
</fileset>
</delete>
</target>
<!-- copies ONLY the swagger-sample jar to dist-->
<target name="fastdist" depends="fastcompile">
<copy todir="dist/lib">
<fileset dir="build">
<include name="*.jar" />
</fileset>
</copy>
</target>
<!-- copies all dependencies into the lib folder -->
<target name="resolve" description="retreive dependencies with ivy">
<ivy:retrieve pattern="${basedir}/lib/[artifact]-[revision].[ext]" conf="build" />
</target>
<target name="fastcompile" description="builds the module without artifact resolution or cleaning">
<delete quiet="true" file="build/${organization}-${artifact}-*.${artifact.ext}" />
<mkdir dir="build" />
<mkdir dir="build/main" />
<mkdir dir="build/main/java" />
<javac srcdir="src/main/java" debug="true" destdir="build/main/java">
<classpath>
<fileset dir="lib">
<include name="*.jar" />
</fileset>
<fileset dir="lib/ext">
<include name="*.jar" />
</fileset>
<pathelement location="build/main/java" />
</classpath>
</javac>
<scalac srcdir="src/main/java:src/main/scala" destdir="build/main/java">
<classpath>
<pathelement location="build/main/java" />
<fileset dir="lib">
<include name="*.jar" />
</fileset>
<fileset dir="lib/ext">
<include name="*.jar" />
</fileset>
<fileset dir="${scala.home}/lib"/>
</classpath>
<include name="**/*.scala" />
<include name="**/*.java" />
</scalac>
<jar jarfile="build/${module}-${version.identifier}.${artifact.ext}">
<fileset dir="build/main/java" />
</jar>
</target>
<!-- cleans up the dist -->
<target name="dist.clean" description="cleans the distribution folder">
<delete quiet="true" dir="dist" />
<delete quiet="true" file="dist.zip" />
</target>
<target name="dependency.tree" description="builds a graphml dependency diagram for viewing with yEd">
<ivy:report conf="build" graph="true" todir="." outputpattern="[artifact]-[revision].[ext]" />
</target>
</project>

31
conf/scala/sample/ivy.xml Normal file
View File

@ -0,0 +1,31 @@
<ivy-module version="2.0">
<info organisation="wordnik" module="sample-java-lib"/>
<configurations>
<conf name="build" description="build wordnik-java"/>
<conf name="test" visibility="public"/>
<conf name="source" visibility="public"/>
<conf name="pom" visibility="public"/>
</configurations>
<dependencies>
<!-- jersey dependencies -->
<dependency org="junit" name="junit" rev="4.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-json" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-client" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-server" rev="1.4" conf="build->default"/>
<dependency org="com.sun.jersey" name="jersey-core" rev="1.4" conf="build->default"/>
<dependency org="asm" name="asm-parent" rev="3.1" conf="build->default"/>
<dependency org="commons-beanutils" name="commons-beanutils" rev="1.8.0" conf="build->default"/>
<dependency org="org.antlr" name="stringtemplate" rev="3.2" conf="build->default"/>
<!-- jackson jars -->
<dependency org="org.codehaus.jackson" name="jackson-jaxrs" rev="1.7.1" conf="build->default"/>
<dependency org="org.codehaus.jackson" name="jackson-xc" rev="1.7.1" conf="build->default"/>
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.7.1" conf="build->default"/>
<dependency org="net.sourceforge.cobertura" name="cobertura" rev="1.9.2" conf="test->default">
<exclude org="asm" name="asm-tree"/>
<exclude org="asm" name="asm"/>
</dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivysettings>
<settings defaultResolver="chained" />
<property name="ivy.checksums" value=""/>
<property name="ivy.local.default.root" value="${ivy.default.ivy.user.dir}/local"
override="false" />
<property name="ivy.local.default.ivy.pattern"
value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
override="false" />
<property name="ivy.local.default.artifact.pattern"
value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]"
override="false" />
<resolvers>
<chain name="chained" returnFirst="true">
<filesystem name="local">
<ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}" />
<artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
</filesystem>
<ibiblio name="ibiblio" m2compatible="true" />
<ibiblio name="javanet" root="http://download.java.net/maven/2/" m2compatible="true" />
</chain>
</resolvers>
</ivysettings>

View File

@ -0,0 +1,27 @@
{
"apiUrl":"http://localhost:8002/api/",
"apiKey":"special-key",
"defaultServiceBaseClass":"Object",
"defaultModelBaseClass":"Object",
"serviceBaseClasses":{},
"defaultModelImports":[],
"defaultServiceImports":[],
"modelPackageName":"com.wordnik.swagger.sample.sdk.java.model",
"apiPackageName":"com.wordnik.swagger.sample.sdk.java.api",
"ignoreMethods":[],
"ignoreModels":[],
"outputDirectory":"../swagger-sample-app/sdk-libs/src/main/java/com/wordnik/swagger/sample/sdk/java",
"libraryHome":"../swagger-sample-app/sdk-libs"
}

View File

@ -0,0 +1,42 @@
{
"userList":[
{
"username":"testuser1",
"password":"password1",
"email":"test1@dummy.com"
},
{
"username":"testuser2",
"password":"password2",
"email":"test2@dummy.com"
}
],
"petList":[
{
"id":101,
"name":"pet1",
"photoUrls":["url1","url2"],
"tags":[
{
"id":1,
"name":"tag1"
},
{
"id":2,
"name":"tag2"
}
],
"status":"available",
"category":{"id":1,"name":"cat1"}
}
],
"orderList":[
{
"id":101,
"petId":1,
"quantity":1,
"status":"placed",
"shipDate":13456789
}
]
}

View File

@ -0,0 +1,265 @@
{
"resources" : [
{
"id" : 1,
"name" : "Find Per by Id",
"httpMethod" : "GET",
"path" : "/pet.{format}/{petId}",
"suggestedMethodName" : "getPetById"
},
{
"id" : 2,
"name" : "Find pets by status",
"httpMethod" : "GET",
"path" : "/pet.{format}/findByStatus",
"suggestedMethodName" : "findPetsByStatus"
},
{
"id" : 3,
"name" : "Find pets by tags",
"httpMethod" : "GET",
"path" : "/pet.{format}/findByTags",
"suggestedMethodName" : "findPetsByTags"
},
{
"id" : 4,
"name" : "Add a pet",
"httpMethod" : "POST",
"path" : "/pet.{format}",
"suggestedMethodName" : "addPet"
},
{
"id" : 5,
"name" : "Update a pet",
"httpMethod" : "PUT",
"path" : "/pet.{format}",
"suggestedMethodName" : "updatePet"
},
{
"id" : 6,
"name" : "Create user",
"httpMethod" : "POST",
"path" : "/user.{format}",
"suggestedMethodName" : "createUser"
},
{
"id" : 7,
"name" : "Update user",
"httpMethod" : "PUT",
"path" : "/user.{format}/{username}",
"suggestedMethodName" : "updateUser"
},
{
"id" : 8,
"name" : "Delete user",
"httpMethod" : "DELETE",
"path" : "/user.{format}/{username}",
"suggestedMethodName" : "deleteUser"
},
{
"id" : 9,
"name" : "Get user by user name",
"httpMethod" : "GET",
"path" : "/user.{format}/{username}",
"suggestedMethodName" : "getUserByName"
},
{
"id" : 10,
"name" : "Login",
"httpMethod" : "GET",
"path" : "/user.{format}/login",
"suggestedMethodName" : "loginUser"
},
{
"id" : 11,
"name" : "Logout",
"httpMethod" : "GET",
"path" : "/user.{format}/logout",
"suggestedMethodName" : "logoutUser"
},
{
"id" : 12,
"name" : "Find order by id",
"httpMethod" : "GET",
"path" : "/store.{format}/order/{orderId}",
"suggestedMethodName" : "getOrderById"
},
{
"id" : 13,
"name" : "Delete order by id",
"httpMethod" : "DELETE",
"path" : "/store.{format}/order/{orderId}",
"suggestedMethodName" : "deleteOrder"
},
{
"id" : 14,
"name" : "Create order",
"httpMethod" : "POST",
"path" : "/store.{format}/order",
"suggestedMethodName" : "placeOrder"
}
],
"testSuites" : [
{
"id" : 1,
"name" : "Test User service related APIs",
"testCases" : [
{
"name" : "Create User",
"id" : 1,
"resourceId" : 6,
"input" : {
"postData":"${input.userList[0]}"
},
"assertions" : [
{
"actualOutput" : "${output(1.1)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
},
{
"name" : "Login User",
"id" : 2,
"resourceId" : 10,
"input" : {
"username":"${input.userList[0].username}",
"password":"${input.userList[0].password}"
},
"assertions" : [
{
"actualOutput" : "${output(1.2)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
},
{
"name" : "Find user by name",
"id" : 3,
"resourceId" : 9,
"input" : {
"username":"${input.userList[0].username}"
},
"assertions" : [
{
"actualOutput" : "${output(1.3).username}",
"condition" : "==",
"expectedOutput" : "${input.userList[0].username}"
}
]
},
{
"name" : "Delete user by name",
"id" : 4,
"resourceId" : 9,
"input" : {
"username":"${input.userList[0].username}"
},
"assertions" : [
{
"actualOutput" : "${output(1.4)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
}
]
},
{
"id" : 2,
"name" : "Test Pet service related APIs",
"testCases" : [
{
"name" : "Add pet",
"id" : 1,
"resourceId" : 4,
"input" : {
"postData":"${input.petList[0]}"
},
"assertions" : [
{
"actualOutput" : "${output(2.1)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
},
{
"name" : "Find pet by id",
"id" : 2,
"resourceId" : 1,
"input" : {
"petId":"1"
},
"assertions" : [
{
"actualOutput" : "${output(2.2)}",
"condition" : "!=",
"expectedOutput" : "NULL"
}
]
},
{
"name" : "Find pet by status",
"id" : 3,
"resourceId" : 2,
"input" : {
"status":"available,sold,pending"
},
"assertions" : [
{
"actualOutput" : "${output(2.3).size}",
"condition" : ">",
"expectedOutput" : "0"
}
]
}
]
},
{
"id" : 3,
"name" : "Test Store service related APIs",
"testCases" : [
{
"name" : "Find order by id",
"id" : 1,
"resourceId" : 12,
"input" : {
"orderId":"1"
},
"assertions" : [
{
"actualOutput" : "${output(3.1)}",
"condition" : "!=",
"expectedOutput" : "NULL"
}
]
},
{
"name" : "Place order",
"id" : 2,
"resourceId" : 14,
"input" : {
"postData":"${input.orderList[0]}"
},
"assertions" : [
{
"actualOutput" : "${output(1.2)}",
"condition" : "!=",
"expectedOutput" : "EXCEPTION"
}
]
}
]
}
]
}

View File

@ -0,0 +1,35 @@
/**
* 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.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation used to provide list of possible values
* @author ramesh
*
*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AllowableValues {
String value() default "";
}

View File

@ -0,0 +1,29 @@
/**
* 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.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodArgumentNames {
String value() default "";
}

View File

@ -0,0 +1,33 @@
/**
* 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.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation used to indicate given property or field is required or not
* @author ramesh
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Required {
}

View File

@ -0,0 +1,268 @@
/**
* 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.common;
import java.io.IOException;
import java.lang.String;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
import java.util.logging.Logger;
import javax.ws.rs.core.MultivaluedMap;
import com.wordnik.swagger.exception.APIException;
import com.wordnik.swagger.exception.APIExceptionCodes;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.DeserializationConfig.Feature;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.type.TypeReference;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.WebResource.Builder;
import com.sun.jersey.api.client.filter.LoggingFilter;
/**
* Provides method to initialize the api server settings and also handles the logic related to invoking the API server
* along with serealizing and deserializing input and output responses.
*
* This is also a Base class for all API classes
*
* @author ramesh
*
*/
public class APIInvoker {
private static String apiServer = "http://api.wordnik.com/v4";
private static SecurityHandler securityHandler = null;
private static boolean loggingEnabled;
private static Logger logger = null;
protected static String POST = "POST";
protected static String GET = "GET";
protected static String PUT = "PUT";
protected static String DELETE = "DELETE";
public static ObjectMapper mapper = new ObjectMapper();
static{
mapper.getDeserializationConfig().set(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.getSerializationConfig().set(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
mapper.configure(SerializationConfig.Feature.WRITE_NULL_PROPERTIES, false);
mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
}
/**
* Initializes the API communication with required inputs.
* @param securityHandler security handler responsible for populating necessary security invocation while making API server calls
* @param apiServer Sets the URL for the API server. It is defaulted to the server
* used while building the driver. This value should be provided while testing the APIs against
* test servers or if there is any changes in production server URLs.
* @param enableLogging This will enable the logging using Jersey logging filter. Refer the following documentation
* for more details. {@link com.sun.jersey.api.client.filter.LoggingFilter}. Default output is sent to system.out.
* Create a logger ({@link java.util.logging.Logger} class and set using setLogger method.
*/
public static void initialize(SecurityHandler securityHandler, String apiServer, boolean enableLogging) {
setSecurityHandler(securityHandler);
if(apiServer != null && apiServer.length() > 0) {
if(apiServer.substring(apiServer.length()-1).equals("/")){
apiServer = apiServer.substring(0, apiServer.length()-1);
}
setApiServer(apiServer);
}
loggingEnabled = enableLogging;
}
/**
* Set the logger instance used for Jersey logging.
* @param aLogger
*/
public static void setLogger(Logger aLogger) {
logger = aLogger;
}
/**
* Gets the API key used for server communication.
* This value is set using initialize method.
* @return
*/
public static SecurityHandler setSecurityHandler() {
return securityHandler;
}
private static void setSecurityHandler(SecurityHandler aSecurityHandler) {
securityHandler = aSecurityHandler;
}
/**
* Sets the URL for the API server. It is defaulted to the server used while building the driver.
* @return
*/
private static String getApiServer() {
return apiServer;
}
public static void setApiServer(String server) {
apiServer = server;
}
/**
* Invokes the API and returns the response as json string.
*
* This is an internal method called by individual APIs for communication. It sets the required security information
* based ons ecuroty handler
*
* @param resourceURL - URL for the rest resource
* @param method - Method we should use for communicating to the back end.
* @param postObject - if the method is POST, provide the object that should be sent as part of post request.
* @return JSON response of the API call.
* @throws com.wordnik.swagger.exception.APIException if the call to API server fails.
*/
public static String invokeAPI(String resourceURL, String method, Map<String,
String> queryParams, Object postData) throws APIException {
Client apiClient = Client.create();
//check for app server values
if(getApiServer() == null || getApiServer().length() == 0) {
String[] args = {getApiServer()};
throw new APIException(APIExceptionCodes.API_SERVER_NOT_VALID, args);
}
//initialize the logger if needed
if(loggingEnabled) {
if(logger == null) {
apiClient.addFilter(new LoggingFilter());
}else{
apiClient.addFilter(new LoggingFilter(logger));
}
}
//make the communication
resourceURL = getApiServer() + resourceURL;
if(queryParams.keySet().size() > 0){
int i=0;
for(String paramName : queryParams.keySet()){
String symbol = "&";
if(i==0){
symbol = "?";
}
resourceURL = resourceURL + symbol + paramName + "=" + queryParams.get(paramName);
i++;
}
}
Map<String, String> headerMap = new HashMap<String, String>();
if(securityHandler != null){
securityHandler.populateSecurityInfo(resourceURL, headerMap);
}
WebResource aResource = apiClient.resource(resourceURL);
//set the required HTTP headers
Builder builder = aResource.type("application/json");
for(String key : headerMap.keySet()){
builder.header(key, headerMap.get(key));
}
ClientResponse clientResponse = null;
if(method.equals(GET)) {
clientResponse = builder.get(ClientResponse.class);
}else if (method.equals(POST)) {
clientResponse = builder.post(ClientResponse.class, serialize(postData));
}else if (method.equals(PUT)) {
clientResponse = builder.put(ClientResponse.class, serialize(postData));
}else if (method.equals(DELETE)) {
clientResponse = builder.delete(ClientResponse.class);
}
//process the response
if(clientResponse.getClientResponseStatus() == ClientResponse.Status.OK) {
String response = clientResponse.getEntity(String.class);
return response;
}else{
int responseCode = clientResponse.getClientResponseStatus().getStatusCode() ;
throw new APIException(responseCode, clientResponse.getEntity(String.class));
}
}
/**
* De-serialize the object from String to object of type input class name.
* @param response
* @param inputClassName
* @return
*/
public static Object deserialize(String response, Class inputClassName) throws APIException {
try {
Object responseObject = mapper.readValue(response, inputClassName);
return responseObject;
} catch (IOException ioe) {
String[] args = new String[]{response, inputClassName.toString()};
throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JSON_TO_JAVA, args, "Error in coversting response json value to java object : " + ioe.getMessage(), ioe);
}
}
/**
* serialize the object from String to input object.
* @param input
* @return
*/
public static String serialize(Object input) throws APIException {
try {
if(input != null) {
return mapper.writeValueAsString(input);
}else{
return "";
}
} catch (IOException ioe) {
throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JAVA_TO_JSON, "Error in coverting input java to json : " + ioe.getMessage(), ioe);
}
}
/**
* Overloaded method for returning the path value
* For a string value an empty value is returned if the value is null
* @param value
* @return
*/
public static String toPathValue(String value) {
return value == null ? "" : value;
}
/**
* Overloaded method for returning a path value
* For a list of objects a comma separated string is returned
* @param objects
* @return
*/
public static String toPathValue(List objects) {
StringBuilder out = new StringBuilder();
for(Object o: objects){
out.append(o.toString());
out.append(",");
}
if(out.indexOf(",") != -1) {
return out.substring(0, out.lastIndexOf(",") );
}
return out.toString();
}
}

View File

@ -0,0 +1,47 @@
/**
* 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.common;
import java.util.Map;
/**
* Provide methods that are responsible for handling security aspect while communicating with the backend server.
*
* Example: For some cases API key may need to be passed in the headers for all server communication and some times
* user authentication token may need to be passed along with api key.
*
* Implementers of this class are responsible for handling storing information related to secutiry and sending it
* along with all API calls
*
* User: ramesh
* Date: 4/12/11
* Time: 5:46 PM
*/
public interface SecurityHandler {
/**
* Populate the security infomration in http headers map and/or reqsource URL.
*
* Value spopulated in the http headers map will be set as http headers while making the server communication.
*
* Depending on the usecase requried information can be added to either of them or both.
*
* @param resourceURL
* @param headers
*/
public void populateSecurityInfo(String resourceURL, Map<String, String> httpHeaders);
}

View File

@ -0,0 +1,38 @@
/**
* 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.common;
/**
* Created by IntelliJ IDEA.
* User: ramesh
* Date: 4/12/11
* Time: 5:46 PM
* To change this template use File | Settings | File Templates.
*/
public class StringValue {
String word;
public String getWord() {
return word;
}
public void setWord(String value) {
this.word = value;
}
}

View File

@ -0,0 +1,100 @@
/**
* 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.exception;
import com.sun.jersey.api.client.ClientResponse;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* Exception that is thrown if there are any issues in invoking Wordnik API.
*
* Each exception carries a code and message. Code can be either HTTP error response code {@link com.sun.jersey.api.client.ClientResponse.Status}
* or The list of possible Wordnik exception code that are listed in the interface {@link APIExceptionCodes}.
* User: ramesh
* Date: 3/31/11
* Time: 9:27 AM
*/
public class APIException extends Exception {
private String message;
private int code;
private String[] args;
@JsonCreator
public APIException() {
}
public APIException(String message) {
super(message);
}
public APIException(int code) {
this.code = code;
}
public APIException(int code, String message, Throwable t) {
super(message, t);
this.message = message;
this.code = code;
}
public APIException(int code, String[] args, String message, Throwable t) {
super(message, t);
this.message = message;
this.code = code;
this.args = args;
}
public APIException(int code, String message) {
super(message);
this.message = message;
this.code = code;
}
public APIException(int code, String[] args, String message) {
super(message);
this.message = message;
this.code = code;
this.args = args;
}
public APIException(int code, String[] args) {
this.code = code;
this.args = args;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}

View File

@ -0,0 +1,54 @@
/**
* 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.exception;
/**
* Lists all the possible exception codes
* @author ramesh
*
*/
public interface APIExceptionCodes {
/**
* System exception.
*/
public static final int SYSTEM_EXCEPTION = 0;
/**
* With Arguments as current key.
*/
public static final int API_KEY_NOT_VALID = 1000;
/**
* With arguments as current token value
*/
public static final int AUTH_TOKEN_NOT_VALID = 1001;
/**
* With arguments as input JSON and output class anme
*/
public static final int ERROR_CONVERTING_JSON_TO_JAVA = 1002;
/**
* With arguments as JAVA class name
*/
public static final int ERROR_CONVERTING_JAVA_TO_JSON = 1003;
public static final int ERROR_FROM_WEBSERVICE_CALL = 1004;
/**
* With arguments as current API server name
*/
public static final int API_SERVER_NOT_VALID = 1005;
}

View File

@ -0,0 +1,31 @@
/**
* Copyright 2011 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package $packageName$
$imports:{ import |
import $import$;
}$
/**
* $enum.description$
* NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
* @author tony
*
*/
object $className$ {
$values: { value | var $value.name$ = $value.value$};separator="\n"$
}

View File

@ -0,0 +1,63 @@
/**
* Copyright 2011 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package $packageName$
import com.wordnik.swagger.runtime.annotations._
import scala.reflect.BeanProperty
import scala.collection.JavaConversions._
$imports:{ import |
import $import$
}$
/**
* $model.description$
*
* NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
*
* @author tony
*
*/
class $className$ extends $extends$ {
$fields:{ field |
/**
* $field.description$
* $if(field.required)$@Required$endif$
* $if(field.allowableValues)$@AllowableValues(value="$field.allowedValuesString$")$endif$
*/
$if(field.fieldDefinition.hasListResponse)$
var $field.fieldDefinition.name$ $field.fieldDefinition.initialization$
def get$field.fieldDefinition.NameForMethod$:java.util.List[$field.fieldDefinition.collectionItemType$] = {
$field.fieldDefinition.name$.toList
}
def set$field.fieldDefinition.NameForMethod$(args:java.util.List[$field.fieldDefinition.collectionItemType$]) = {
$field.fieldDefinition.name$.clear
args.foreach(arg=>$field.fieldDefinition.name$ += arg)
}
$\r$
$else$
@BeanProperty
var $field.fieldDefinition.name$:$field.fieldDefinition.returnType$ $field.fieldDefinition.initialization$$\r\r$
$endif$
}$ override def toString:String = {
"[" +
$fields:{ field | "$field.fieldDefinition.name$:" + $field.fieldDefinition.name$};separator=" + \r "$ + "]"
}
}

View File

@ -0,0 +1,137 @@
/**
* Copyright 2011 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package $packageName$
import $modelPackageName$._
import org.codehaus.jackson.map.DeserializationConfig.Feature
import org.codehaus.jackson.map.ObjectMapper
import org.codehaus.jackson.`type`.TypeReference
import com.wordnik.swagger.runtime.annotations._
import com.wordnik.swagger.runtime.common._
import com.wordnik.swagger.runtime.exception._
import java.io.IOException
import scala.collection.mutable._
import scala.collection.JavaConversions._
$imports:{ import |
import $import$
}$
/**
*
* NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
* @author tony
*
*/
object $resource$ {
$methods:{ method |
/**
* $method.title$
*
$if(method.description)$
* $method.description$
* $endif$
* $method.arguments:{ argument |@param $argument.name$ $argument.description$
$if(argument.allowedValues)$
* Allowed values are - $argument.allowedValues$ $endif$ }$
$if(!method.responseVoid)$
* @return $method.returnValue$ {@link $method.returnClassName$} $endif$
* @throws APIException $method.exceptionDescription$
*/
$if(method.hasArguments)$
@MethodArgumentNames(value="$method.argumentNames; separator=", "$")
$endif$
@throws(classOf[APIException])
def $method.name$($method.argumentDefinitions; separator=", "$) $if(method.hasResponseValue)$:$method.returnValue$$endif$ = {
//parse inputs
var resourcePath = "$method.resourcePath$".replace("{format}","json")
val method = "$method.methodType$";
var queryParams = new HashMap[String, String]
$if(!method.inputModel)$
$method.queryParameters:{ argument |
if(null != $argument.name$) {
queryParams += "$argument.name$" -> APIInvoker.toPathValue($argument.name$)
}
}$
$method.pathParameters:{ argument |
if(null != $argument.name$) {
resourcePath = resourcePath.replace("{$argument.name$}", $argument.name$)
}
}$
$endif$
$if(method.inputModel)$
$method.queryParameters:{ argument |
if(null != $argument.inputModelClassArgument$ && null != $argument.methodNameFromModelClass$ ) {
queryParams += "$argument.name$" -> $argument.methodNameFromModelClass$)
}
}$
$method.pathParameters:{ argument |
if(null != $argument.inputModelClassArgument$ && null != $argument.methodNameFromModelClass$ ) {
resourcePath = resourcePath.replace("{$argument.name$}", $argument.methodNameFromModelClass$)
}
}$
$endif$
//make the API Call
$if(method.hasResponseValue)$
$if(method.postObject)$
val response = APIInvoker.invokeAPI(resourcePath, method, queryParams, postData)
$else$
val response = APIInvoker.invokeAPI(resourcePath, method, queryParams, null)
$endif$
$else$
$if(method.postObject)$
APIInvoker.invokeAPI(resourcePath, method, queryParams, postData)
$else$
APIInvoker.invokeAPI(resourcePath, method, queryParams, null)
$endif$
$endif$
$if(!method.responseVoid)$
$if(method.hasResponseValue)$
if(null == response || response.length() == 0){
null
}
$endif$
$if(!method.returnValueList)$
$if(method.hasResponseValue)$
//create output objects if the response has more than one object
val responseObject = APIInvoker.deserialize(response, classOf[$method.returnClassName$]).asInstanceOf[$method.returnValue$]
responseObject
$endif$
$endif$
$if(method.returnValueList)$
val typeRef = new TypeReference[Array[$method.returnClassName$]] {}
try {
val responseObject = APIInvoker.mapper.readValue(response, typeRef).asInstanceOf[Array[$method.returnClassName$]]
responseObject.toList
} catch {
case ioe:IOException => {
val args = Array(response, typeRef.toString())
throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JSON_TO_JAVA, args, "Error in converting response json value to java object : " + ioe.getMessage(), ioe)
}
case _ => throw new APIException(APIExceptionCodes.ERROR_CONVERTING_JSON_TO_JAVA, "Error in converting response json value to java object")
}
$endif$
$endif$
}
}$
}

View File

@ -0,0 +1,33 @@
/**
* Copyright 2011 Wordnik, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package $packageName$
/**
*
* Maintains the compatible server version against which the drive is written
* NOTE: This class is auto generated by the swagger code generator program. Do not edit the class manually.
* @author tony
*
*/
class VersionChecker {
var compatibleVersion = "$apiVersion$"
/**
* Gets the version against which the library code was written
*/
def getCompatibleVersion():String = compatibleVersion
}

View File

@ -33,11 +33,47 @@ public class FieldDefinition {
private String collectionItemName; private String collectionItemName;
private boolean hasListResponse;
private boolean hasMapResponse;
private boolean hasSetResponse;
public boolean isHasListResponse() {
return hasListResponse;
}
public void setHasListResponse(boolean hasListResponse) {
this.hasListResponse = hasListResponse;
}
public boolean isHasMapResponse() {
return hasMapResponse;
}
public void setHasMapResponse(boolean hasMapResponse) {
this.hasMapResponse = hasMapResponse;
}
public boolean isHasSetResponse() {
return hasSetResponse;
}
public void setHasSetResponse(boolean hasSetResponse) {
this.hasSetResponse = hasSetResponse;
}
public String getReturnType() { public String getReturnType() {
return returnType; return returnType;
} }
public void setReturnType(String returnType) { public void setReturnType(String returnType) {
if(returnType.startsWith("List")){
hasListResponse = true;
}else if(returnType.startsWith("Set")){
hasSetResponse = true;
}else if(returnType.startsWith("Map")){
hasMapResponse = true;
}
this.returnType = returnType; this.returnType = returnType;
} }

View File

@ -19,7 +19,6 @@ import com.wordnik.swagger.codegen.api.SwaggerResourceDocReader;
import com.wordnik.swagger.codegen.config.*; import com.wordnik.swagger.codegen.config.*;
import com.wordnik.swagger.codegen.config.ApiConfiguration; import com.wordnik.swagger.codegen.config.ApiConfiguration;
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider; import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider;
import com.wordnik.swagger.codegen.config.java.JavaDataTypeMappingProvider;
import com.wordnik.swagger.codegen.exception.CodeGenerationException; import com.wordnik.swagger.codegen.exception.CodeGenerationException;
import com.wordnik.swagger.codegen.resource.*; import com.wordnik.swagger.codegen.resource.*;
import org.antlr.stringtemplate.StringTemplate; import org.antlr.stringtemplate.StringTemplate;
@ -56,8 +55,13 @@ public class LibraryCodeGenerator {
protected RulesProvider codeGenRulesProvider; protected RulesProvider codeGenRulesProvider;
protected NamingPolicyProvider nameGenerator; protected NamingPolicyProvider nameGenerator;
public LibraryCodeGenerator(String configPath){ public LibraryCodeGenerator(){}
public LibraryCodeGenerator(String configPath){
initializeWithConfigPath(configPath);
}
protected void initializeWithConfigPath(String configPath){
final ObjectMapper mapper = new ObjectMapper(); final ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@ -65,14 +69,15 @@ public class LibraryCodeGenerator {
this.setApiConfig(readApiConfiguration(configPath, mapper, configFile)); this.setApiConfig(readApiConfiguration(configPath, mapper, configFile));
this.setCodeGenRulesProvider(readRulesProviderConfig(configPath, mapper, configFile)); this.setCodeGenRulesProvider(readRulesProviderConfig(configPath, mapper, configFile));
this.setLanguageConfig( initializeLangConfig(readLanguageConfiguration(configPath, mapper, configFile)) ); this.setLanguageConfig( initializeLangConfig(readLanguageConfiguration(configPath, mapper, configFile)) );
this.setDataTypeMappingProvider(new JavaDataTypeMappingProvider());
this.setNameGenerator(new CamelCaseNamingPolicyProvider());
} }
public LibraryCodeGenerator(String apiServerURL, String apiKey, String modelPackageName, String apiPackageName, public LibraryCodeGenerator(String apiServerURL, String apiKey, String modelPackageName, String apiPackageName,
String classOutputDir, String libraryHome){ String classOutputDir, String libraryHome){
initialize(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome);
}
protected void initialize(String apiServerURL, String apiKey, String modelPackageName, String apiPackageName,
String classOutputDir, String libraryHome){
final ObjectMapper mapper = new ObjectMapper(); final ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ApiConfiguration aApiConfiguration = new ApiConfiguration(); ApiConfiguration aApiConfiguration = new ApiConfiguration();
@ -88,9 +93,6 @@ public class LibraryCodeGenerator {
aLanguageConfiguration.setLibraryHome(libraryHome); aLanguageConfiguration.setLibraryHome(libraryHome);
initializeLangConfig(aLanguageConfiguration); initializeLangConfig(aLanguageConfiguration);
this.setLanguageConfig(aLanguageConfiguration); this.setLanguageConfig(aLanguageConfiguration);
this.setDataTypeMappingProvider(new JavaDataTypeMappingProvider());
this.setNameGenerator(new CamelCaseNamingPolicyProvider());
} }
/** /**
@ -354,7 +356,7 @@ public class LibraryCodeGenerator {
template.setAttribute("extends", config.getServiceBaseClass(className)); template.setAttribute("extends", config.getServiceBaseClass(className));
File aFile = new File(languageConfig.getResourceClassLocation()+ resource.generateClassName(nameGenerator) +languageConfig.getClassFileExtension()); File aFile = new File(languageConfig.getResourceClassLocation()+ resource.generateClassName(nameGenerator) +languageConfig.getClassFileExtension());
writeFile(aFile, template.toString(), "API CLasses"); writeFile(aFile, template.toString(), "API Classes");
}catch(RuntimeException t){ }catch(RuntimeException t){
System.out.println("Failed generating api class for the resource : " + resource.getResourcePath()); System.out.println("Failed generating api class for the resource : " + resource.getResourcePath());
throw t; throw t;

View File

@ -56,6 +56,16 @@ public class ResourceMethod {
private Model listWrapperModel; private Model listWrapperModel;
private boolean hasResponseValue;
public boolean isHasResponseValue(){
return hasResponseValue;
}
public void setHasResponseValue(boolean hasResponseValue){
this.hasResponseValue = hasResponseValue;
}
public String getTitle() { public String getTitle() {
return title; return title;
} }

View File

@ -103,6 +103,17 @@ public interface DataTypeMappingProvider {
*/ */
public String generateSetInitialization(String typeClass); public String generateSetInitialization(String typeClass);
/**
* Sets variable initialization.
*
* Example: In scala initializing a variable with an unknown value will be:
* <Code>
* var age:String = _
* </Code>
* @return
*/
public String generateVariableInitialization(String typeClass);
/** /**
* Gets list of items that needs to be included when referring list objects in model or resource classes. * Gets list of items that needs to be included when referring list objects in model or resource classes.
* *

View File

@ -182,4 +182,9 @@ public class As3DataTypeMappingProvider implements DataTypeMappingProvider {
} }
return classShortName; return classShortName;
} }
@Override
public String generateVariableInitialization(String typeClass) {
return "";
}
} }

View File

@ -217,4 +217,9 @@ public class JavaDataTypeMappingProvider implements DataTypeMappingProvider {
return nameGenerator.applyClassNamingPolicy(type); return nameGenerator.applyClassNamingPolicy(type);
} }
} }
@Override
public String generateVariableInitialization(String typeClass) {
return "";
}
} }

View File

@ -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.scala
import com.wordnik.swagger.codegen.config.DataTypeMappingProvider
import com.wordnik.swagger.codegen.config.NamingPolicyProvider
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider
import scala.collection.mutable._
import scala.collection.JavaConversions._
object ScalaDataTypeMappingProvider {
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 ScalaDataTypeMappingProvider extends DataTypeMappingProvider {
val nameGenerator = new CamelCaseNamingPolicyProvider()
def isPrimitiveType(input: String): Boolean = {
ScalaDataTypeMappingProvider.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) {
ScalaDataTypeMappingProvider.primitiveObjectMap(input)
} else {
ScalaDataTypeMappingProvider.primitiveValueMap(input)
}
}
case _ => nameGenerator.applyClassNamingPolicy(input)
}
}
}

View File

@ -0,0 +1,93 @@
/**
* 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.scala
import com.wordnik.swagger.codegen.LibraryCodeGenerator
import com.wordnik.swagger.codegen.config.LanguageConfiguration
import com.wordnik.swagger.codegen.config.common.CamelCaseNamingPolicyProvider
import com.wordnik.swagger.codegen.exception.CodeGenerationException
import com.wordnik.swagger.codegen.util.FileUtil
import java.io.File
object ScalaLibCodeGen {
def main(args: Array[String]) = {
val codeGenerator = args.length match {
case 1 => new ScalaLibCodeGen(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 + ".model"
val apiPackageName = packageName + ".api"
val classOutputDir = libraryHome + "/src/main/scala/" + packageName.replace(".", "/")
new ScalaLibCodeGen(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 ScalaLibCodeGen(
apiServerURL: String,
apiKey: String,
modelPackageName: String,
apiPackageName: String,
classOutputDir: String,
libraryHome: String,
configPath: String) extends LibraryCodeGenerator {
if (null != configPath) {
initializeWithConfigPath(configPath)
this.setDataTypeMappingProvider(new ScalaDataTypeMappingProvider())
this.setNameGenerator(new CamelCaseNamingPolicyProvider())
}
else{
initialize(apiServerURL, apiKey, modelPackageName, apiPackageName, classOutputDir, libraryHome)
setDataTypeMappingProvider(new ScalaDataTypeMappingProvider())
setNameGenerator(new CamelCaseNamingPolicyProvider())
}
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(".scala");
config.setTemplateLocation("conf/scala/templates");
config.setStructureLocation("conf/scala/structure");
config.setExceptionPackageName("com.wordnik.swagger.exception");
config.setAnnotationPackageName("com.wordnik.swagger.annotations");
//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/java/com/wordnik/swagger/runtime");
FileUtil.createOutputDirectories(config.getLibraryHome() + "/src/main/java/com/wordnik/swagger/runtime", "java");
FileUtil.copyDirectory(new File("src/main/java/com/wordnik/swagger/runtime"), new File(config.getLibraryHome() + "/src/main/java/com/wordnik/swagger/runtime"));
config
}
}

View File

@ -303,6 +303,13 @@ public class EndpointOperation {
method.setMethodType(this.getHttpMethod()); method.setMethodType(this.getHttpMethod());
//get return value //get return value
String returnType = dataTypeMapper.getClassType(responseClass, false);
if("".equals(returnType)){
method.setHasResponseValue(false);
}
else{
method.setHasResponseValue(true);
}
method.setReturnValue(dataTypeMapper.getClassType(responseClass, false)); method.setReturnValue(dataTypeMapper.getClassType(responseClass, false));
method.setReturnClassName(dataTypeMapper.getGenericType(responseClass)); method.setReturnClassName(dataTypeMapper.getGenericType(responseClass));

View File

@ -229,10 +229,10 @@ public class ModelField {
fieldDefinition.setName(this.getName()); fieldDefinition.setName(this.getName());
} }
}else{ }else{
fieldDefinition.setInitialization(dataTypeMapper.generateVariableInitialization(type));
fieldDefinition.setReturnType(dataTypeMapper.getClassType(type, false)); fieldDefinition.setReturnType(dataTypeMapper.getClassType(type, false));
fieldDefinition.setName(this.getName()); fieldDefinition.setName(this.getName());
} }
} }
return fieldDefinition; return fieldDefinition;
} }