package com.google.code.apis.rest.client.CodeGeneration;
import java.util.Iterator;
import java.util.Vector;
import com.google.code.apis.rest.client.GUI.SettingsDialog;
import com.google.code.apis.rest.client.Tree.MethodItem;
import com.google.code.apis.rest.client.Wadl.Analyzer;
import com.google.gwt.core.client.GWT;
/**
* @author Louis Botterill
*/
public class CSharpGenerator {
private static Templates_CSharp templates_CSharp;
private String code = "";
private String packageName = "";
private String interfaceList = "";
private String basePath = "";
public CSharpGenerator(String packageName) {
this.packageName = packageName;
templates_CSharp = (Templates_CSharp) GWT.create(Templates_CSharp.class);
}
protected String generate(Vector faults) {
// the fault handling string
String errorHandlingString = prepareFaults(faults); // LB faults not currently used
String restRequestClass = templates_CSharp.restRequestClass(basePath, interfaceList);
// add the CSharp file template around the classes
restRequestClass = templates_CSharp.defFile(restRequestClass, packageName);
// add it to the other generated request classes
code += restRequestClass;
return code;
}
/**
* @param faults
* @return
*/
private String prepareFaults(Vector faults) {
String errorHandling = "";
return errorHandling;
}
public void createRequestClass(RequestMessager requestMessager) {
Iterator variablesIterator = requestMessager.getVariables().iterator();
// create a list of method "interfaces" to define the overall service interface...
requestMessager.getAbsoluteAdress();
if (interfaceList.length() > 0)
{
interfaceList += ", ";
}
interfaceList += requestMessager.getName();
// calculate the base path (host/context) to connect to
basePath = requestMessager.getAbsoluteAdress();
int pos = basePath.lastIndexOf(("/"));
basePath = basePath.substring(0, pos);
String templateString = "";
String methodParams = "";
pos = 0;
while (variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
if (pos > 0)
{
templateString += "&";
methodParams += ", ";
}
templateString += parameter.getName() + "=" + "{" + parameter.getName() + "}";
methodParams += parameter.getType() + " " + parameter.getName();
pos++;
}
String restMethodDef =
"\t[OperationContract]\n" +
"\t[WebInvoke( \n" +
"\t\tMethod = \"" + requestMessager.getHttpMethodName() + "\",\n" +
"\t\tBodyStyle = WebMessageBodyStyle.Bare,\n" +
"\t\tUriTemplate = \"" + requestMessager.getName() + "?" + templateString + "\"\n" +
"\t)]\n" +
"\tStream " + requestMessager.getName() + "(" + methodParams + ");\n";
String requestClass = templates_CSharp.defClass(
requestMessager.getName(),
restMethodDef
);
code += templates_CSharp.defFile(requestClass, this.packageName);
}
/**
* @param variables
* @return
*
* sorts the variables vector by visibility (public < protected < private)
*/
private Vector sortByVisibility(Vector variables) {
Vector sortedVars = new Vector();
Iterator variablesIterator = variables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
if (parameter.getAccess().equals(Parameter.accessPublic)) {
sortedVars.insertElementAt(parameter, 0);
}
else if (parameter.getAccess().equals(Parameter.accessProtected)) {
sortedVars.add(parameter);
}
}
variablesIterator = variables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
if (parameter.getAccess().equals(Parameter.accessPrivate)) {
sortedVars.add(parameter);
}
}
return sortedVars;
}
/**
* creates the string (sorted by visibility)
* public varname // required
* private _varname // optional
*
*/
private String prepareClassVars(Vector variables) {
variables = sortByVisibility(variables);
String classVarsString = "";
Iterator variablesIterator = variables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
classVarsString += "\t" + parameter.getAccess() + " " + parameter.getType() + " " + parameter.getName() + ";";
if (parameter.isRequired()) {
classVarsString += " // required";
}
else {
classVarsString += " // optional";
}
if (variablesIterator.hasNext()) {
classVarsString += "\n";
}
}
return classVarsString;
}
/**
* @param className
* @param requiredVariables
* @param optionalVariables
* @return
*/ /*
private String prepareConstructors(String className, Vector requiredVariables, Vector optionalVariables) {
String constructors = "";
for (int i = 0; i <= optionalVariables.size(); i++) {
Vector constructorVariables = new Vector();
Iterator requiredVariablesIterator = requiredVariables.iterator();
while(requiredVariablesIterator.hasNext()) {
constructorVariables.add(requiredVariablesIterator.next());
}
for(int j = 0; j < i; j++) {
constructorVariables.add(optionalVariables.elementAt(j));
}
//com.google.gwt.user.client.Window.alert(constructorVariables.size() + "");
String constructor = templates_CSharp.defConstructor(
className,
prepareClassParams(constructorVariables),
prepareParamAssignments(constructorVariables),
prepareParamJavaDoc(constructorVariables),
constructorVariables.size() + "");
constructors += constructor;
}
return constructors;
}
*/
/**
* @param constructorVariables
* @return
*/
private String prepareParamJavaDoc(Vector variables) {
String paramJavaDocString = "";
Iterator variablesIterator = variables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
String varName = "";
varName = parameter.getName();
paramJavaDocString += "\t * @param " + varName + "\n";
}
return paramJavaDocString;
}
/**
* @param httpMethodName
* @param absoluteAddress
* @return
*/
private String prepareSubmitRequest(String httpMethodName, String absoluteAddress) {
String submitRequest = "";
if (absoluteAddress.matches(Analyzer.templateParamRegExp)) {
int indexOfOpen = absoluteAddress.indexOf(Analyzer.templateParamOpenChar);
int indexOfClose = absoluteAddress.indexOf(Analyzer.templateParamCloseChar);
while(indexOfOpen >= 0 &&
indexOfClose > 0 &&
indexOfOpen < indexOfClose) {
String templateParamName = absoluteAddress.substring(indexOfOpen + 1, indexOfClose);
String absoluteAddressLeft = absoluteAddress.substring(0, indexOfOpen);
String absoluteAddressRight = absoluteAddress.substring(indexOfClose + 1);
absoluteAddress = absoluteAddressLeft + "\" + " + templateParamName + " + \"" + absoluteAddressRight;
submitRequest += "\t\tString " + templateParamName + " = this.get" + templateParamName.substring(0, 1).toUpperCase() + templateParamName.substring(1) + SettingsDialog.templateSuffix + "();\n";
indexOfOpen = absoluteAddress.indexOf(Analyzer.templateParamOpenChar);
indexOfClose = absoluteAddress.indexOf(Analyzer.templateParamCloseChar);
}
if (absoluteAddress.endsWith(" + \"")) {
absoluteAddress = absoluteAddress.replaceAll("\\s\\+\\s\"$", "");
}
else {
absoluteAddress += "\"";
}
absoluteAddress = absoluteAddress.replaceAll("\\+\\s\"\"\\s\\+", "\\s\\+\\s");
}
else {
absoluteAddress += "\"";
}
submitRequest += "\t\tString requestUri = \"" + absoluteAddress + ";\n";
if (httpMethodName.equals(MethodItem.get)) {
submitRequest += "\t\tString response = this.doGetCall(requestUri + \"?\" + this.prepareParams());";
}
else if (httpMethodName.equals("POST")) {
submitRequest += "\t\tString response = this.doPostCall(requestUri, this.prepareParams());";
}
return submitRequest;
}
/**
* @param variables
* @param optionalVariables
* @return
*
* creates the param1=value1¶m2=value2¶m3=value3 string
*/
private String prepareRestParameters(Vector requiredVariables, Vector optionalVariables) {
String restParamsString = "";
if (CodeGenerator.containsNoOrOnlyTemplateParams(requiredVariables, optionalVariables)) {
restParamsString = "\t\t\tURLEncoder.encode(\"\", \"UTF-8\");";
}
else {
// required variables
Iterator variablesIterator = requiredVariables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
String varName = parameter.getName();
if (!parameter.isTemplateParam()) {
String varName1stLetterUpperCase = varName.substring(0, 1).toUpperCase() + varName.substring(1);
restParamsString += "\t\t\tif (!this.get" + varName1stLetterUpperCase + "().equals(\"\")) \n\t\t\t\tparamString += \"&" + varName + "=\" + " + "URLEncoder.encode(this.get" + varName1stLetterUpperCase + "(), \"UTF-8\"); \n\t\t\telse \n\t\t\t\tSystem.err.println(\"The required parameter '" + varName + "' is missing\");";
if (variablesIterator.hasNext()) {
restParamsString += "\n";
}
}
}
if (restParamsString.length() > 0) {
restParamsString = "\n\t\t\t// required parameters\n" + restParamsString;
}
if (optionalVariables.size() > 0) {
restParamsString += "\n\t\t\t// optional parameters\n";
}
// optional variables
variablesIterator = optionalVariables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
if (!parameter.isTemplateParam()) {
String varName = parameter.getName();
String varName1stLetterUpperCase = varName.substring(0, 1).toUpperCase() + varName.substring(1);
restParamsString += "\t\t\tparamString += (!this.get" + varName1stLetterUpperCase + "().equals(\"\"))?\n\t\t\t\t\"&" + varName + "=\" + " + "URLEncoder.encode(this.get" + varName1stLetterUpperCase + "(), \"UTF-8\") : \"\";";
if (variablesIterator.hasNext()) {
restParamsString += "\n";
}
}
}
}
return restParamsString;
}
/**
* @param variables
* @return
*
* creates the string
* this.param1 = param1
* this.param2 = param2
*/
private String prepareParamAssignments(Vector variables) {
String classParamAssignmentString = "";
Iterator variablesIterator = variables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
String varName = parameter.getName();
classParamAssignmentString += "\t\tthis." + varName + " = " + varName + ";\n";
}
if (variables.size() > 0) {
classParamAssignmentString = "\t\t// assign class variables \n" + classParamAssignmentString;
}
else classParamAssignmentString = "\t\t// empty constructor\n";
return classParamAssignmentString;
}
/**
* creates the string
* String param1, int param2, float param3
*/
private String prepareClassParams(Vector variables) {
String classParamsString = "";
Iterator variablesIterator = variables.iterator();
while(variablesIterator.hasNext()) {
Parameter parameter = (Parameter) variablesIterator.next();
classParamsString += parameter.getType() + " " + parameter.getName();
if (variablesIterator.hasNext()) {
classParamsString += ", ";
}
}
if (classParamsString.length() >= 70) {
classParamsString = "\n\t\t\t" + classParamsString.replaceAll(",\\s", ",\n\t\t\t");
}
return classParamsString;
}
}