summaryrefslogtreecommitdiff
path: root/gentools/src
diff options
context:
space:
mode:
Diffstat (limited to 'gentools/src')
-rw-r--r--gentools/src/org/apache/qpid/gentools/DotnetGenerator.java319
-rw-r--r--gentools/src/org/apache/qpid/gentools/JavaGenerator.java2
-rw-r--r--gentools/src/org/apache/qpid/gentools/Main.java53
3 files changed, 366 insertions, 8 deletions
diff --git a/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java b/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java
new file mode 100644
index 0000000000..3593145db1
--- /dev/null
+++ b/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java
@@ -0,0 +1,319 @@
+package org.apache.qpid.gentools;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.TreeMap;
+
+public class DotnetGenerator extends Generator
+{
+ private class DomainInfo
+ {
+ public String type;
+ public String size;
+ public String encodeExpression;
+ public String decodeExpression;
+ public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression)
+ {
+ this.type = domain;
+ this.size = size;
+ this.encodeExpression = encodeExpression;
+ this.decodeExpression = decodeExpression;
+ }
+ }
+
+ private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>();
+
+ public DotnetGenerator(AmqpVersionSet versionList)
+ {
+ super(versionList);
+ // Load .NET type and size maps.
+ // Adjust or add to these lists as new types are added/defined.
+ // The char '#' will be replaced by the field variable name (any type).
+ // The char '~' will be replaced by the compacted bit array size (type bit only).
+ // TODO: I have left a copy of the Java typeMap here - replace with appropriate .NET values.
+ typeMap.put("bit", new DomainInfo(
+ "boolean", // .NET code type
+ "~", // size
+ "EncodingUtils.writeBooleans(buffer, #)", // encode expression
+ "# = EncodingUtils.readBooleans(buffer)")); // decode expression
+ typeMap.put("content", new DomainInfo(
+ "Content", // .NET code type
+ "EncodingUtils.encodedContentLength(#)", // size
+ "EncodingUtils.writeContentBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readContent(buffer)")); // decode expression
+ typeMap.put("long", new DomainInfo(
+ "long", // .NET code type
+ "4", // size
+ "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression
+ "# = buffer.getUnsignedInt()")); // decode expression
+ typeMap.put("longlong", new DomainInfo(
+ "long", // .NET code type
+ "8", // size
+ "buffer.putLong(#)", // encode expression
+ "# = buffer.getLong()")); // decode expression
+ typeMap.put("longstr", new DomainInfo(
+ "byte[]", // .NET code type
+ "EncodingUtils.encodedLongstrLength(#)", // size
+ "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readLongstr(buffer)")); // decode expression
+ typeMap.put("octet", new DomainInfo(
+ "short", // .NET code type
+ "1", // size
+ "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression
+ "# = buffer.getUnsigned()")); // decode expression
+ typeMap.put("short", new DomainInfo(
+ "int", // .NET code type
+ "2", // size
+ "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression
+ "# = buffer.getUnsignedShort()")); // decode expression
+ typeMap.put("shortstr", new DomainInfo(
+ "AMQShortString", // .NET code type
+ "EncodingUtils.encodedShortStringLength(#)", // size
+ "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression
+ typeMap.put("table", new DomainInfo(
+ "FieldTable", // .NET code type
+ "EncodingUtils.encodedFieldTableLength(#)", // size
+ "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression
+ "# = EncodingUtils.readFieldTable(buffer)")); // decode expression
+ typeMap.put("timestamp", new DomainInfo(
+ "long", // .NET code type
+ "8", // size
+ "EncodingUtils.writeTimestamp(buffer, #)", // encode expression
+ "# = EncodingUtils.readTimestamp(buffer)")); // decode expression
+ }
+
+ @Override
+ protected String prepareFilename(String filenameTemplate,
+ AmqpClass thisClass, AmqpMethod method, AmqpField field)
+ {
+ StringBuffer sb = new StringBuffer(filenameTemplate);
+ if (thisClass != null)
+ replaceToken(sb, "${CLASS}", thisClass.name);
+ if (method != null)
+ replaceToken(sb, "${METHOD}", method.name);
+ if (field != null)
+ replaceToken(sb, "${FIELD}", field.name);
+ return sb.toString();
+ }
+
+ @Override
+ protected void processClassList(StringBuffer sb, int listMarkerStartIndex,
+ int listMarkerEndIndex, AmqpModel model)
+ throws AmqpTemplateException, AmqpTypeMappingException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+// codeSnippet = generateRegistry(model, 8, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processConstantList(StringBuffer sb,
+ int listMarkerStartIndex, int listMarkerEndIndex,
+ AmqpConstantSet constantSet) throws AmqpTemplateException,
+ AmqpTypeMappingException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+// codeSnippet = generateConstantGetMethods(constantSet, 4, 4);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processFieldList(StringBuffer sb, int listMarkerStartIndex,
+ int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version)
+ throws AmqpTypeMappingException, AmqpTemplateException,
+ IllegalAccessException, InvocationTargetException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+// codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod,
+// mangledDeclarationGenerateMethod, 4, 4, this);
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processMethodList(StringBuffer sb, int listMarkerStartIndex,
+ int listMarkerEndIndex, AmqpClass thisClass)
+ throws AmqpTemplateException, AmqpTypeMappingException
+ {
+ String codeSnippet;
+ int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line
+ String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
+ int tokStart = tline.indexOf('$');
+ String token = tline.substring(tokStart).trim();
+ sb.delete(listMarkerStartIndex, lend);
+
+ // TODO: Add in tokens and calls to their corresponding generator methods here...
+ if (token.compareTo("${??????????}") == 0)
+ {
+ codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
+ }
+
+ else // Oops!
+ {
+ throw new AmqpTemplateException("Template token " + token + " unknown.");
+ }
+ sb.insert(listMarkerStartIndex, codeSnippet);
+ }
+
+ @Override
+ protected void processTemplateA(String[] template) throws IOException,
+ AmqpTemplateException, AmqpTypeMappingException,
+ IllegalAccessException, InvocationTargetException
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ processTemplateD(template, null, null, null);
+ }
+
+ @Override
+ protected void processTemplateB(String[] template, AmqpClass thisClass)
+ throws IOException, AmqpTemplateException,
+ AmqpTypeMappingException, IllegalAccessException,
+ InvocationTargetException
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ processTemplateD(template, thisClass, null, null);
+ }
+
+ @Override
+ protected void processTemplateC(String[] template, AmqpClass thisClass,
+ AmqpMethod method) throws IOException, AmqpTemplateException,
+ AmqpTypeMappingException, IllegalAccessException,
+ InvocationTargetException
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ processTemplateD(template, thisClass, method, null);
+ }
+
+ @Override
+ protected void processTemplateD(String[] template, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field) throws IOException,
+ AmqpTemplateException, AmqpTypeMappingException,
+ IllegalAccessException, InvocationTargetException
+ {
+ // I've put in the Java model here - this can be changed if a different pattern is required.
+ StringBuffer sb = new StringBuffer(template[1]);
+ String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field);
+ try { processAllLists(sb, thisClass, method, null); }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("WARNING: " + template[templateFileNameIndex] + ": " + e.getMessage());
+ }
+ try { processAllTokens(sb, thisClass, method, field, null); }
+ catch (AmqpTemplateException e)
+ {
+ System.out.println("WARNING: " + template[templateFileNameIndex] + ": " + e.getMessage());
+ }
+ writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename));
+ generatedFileCounter ++;
+ }
+
+ @Override
+ protected String processToken(String token, AmqpClass thisClass,
+ AmqpMethod method, AmqpField field, AmqpVersion version)
+ throws AmqpTemplateException, AmqpTypeMappingException
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public String getDomainType(String domainName, AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ return globalDomainMap.getDomainType(domainName, version);
+ }
+
+ public String getGeneratedType(String domainName, AmqpVersion version)
+ throws AmqpTypeMappingException
+ {
+ String domainType = globalDomainMap.getDomainType(domainName, version);
+ if (domainType == null)
+ {
+ throw new AmqpTypeMappingException("Domain type \"" + domainName +
+ "\" not found in Java typemap.");
+ }
+ DomainInfo info = typeMap.get(domainType);
+ if (info == null)
+ {
+ throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\"");
+ }
+ return info.type;
+ }
+
+ public String prepareClassName(String className)
+ {
+ return camelCaseName(className, true);
+ }
+
+ public String prepareDomainName(String domainName)
+ {
+ return camelCaseName(domainName, false);
+ }
+
+ public String prepareMethodName(String methodName)
+ {
+ return camelCaseName(methodName, false);
+ }
+
+ private String camelCaseName(String name, boolean upperFirstFlag)
+ {
+ StringBuffer ccn = new StringBuffer();
+ String[] toks = name.split("[-_.\\ ]");
+ for (int i=0; i<toks.length; i++)
+ {
+ StringBuffer b = new StringBuffer(toks[i]);
+ if (upperFirstFlag || i>0)
+ b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0)));
+ ccn.append(b);
+ }
+ return ccn.toString();
+ }
+}
diff --git a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java
index 13560f5c17..84d06cf204 100644
--- a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java
+++ b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java
@@ -1072,7 +1072,7 @@ public class JavaGenerator extends Generator
line.append(bitFieldList.get(i));
}
- sb.append(Utils.createSpaces(indentSize) +
+ sb.append(indent +
typeMap.get("bit").encodeExpression.replaceAll("#", line.toString()) + ";" + cr);
}
return sb.toString();
diff --git a/gentools/src/org/apache/qpid/gentools/Main.java b/gentools/src/org/apache/qpid/gentools/Main.java
index 7e6248817c..f1728ab290 100644
--- a/gentools/src/org/apache/qpid/gentools/Main.java
+++ b/gentools/src/org/apache/qpid/gentools/Main.java
@@ -38,8 +38,11 @@ public class Main
{
private static final String defaultOutDir = ".." + Utils.fileSeparator + "gen";
private static final String defaultCppTemplateDir = ".." + Utils.fileSeparator + "templ.cpp";
+ private static final String defaultDotnetTemplateDir = ".." + Utils.fileSeparator + "templ.net";
private static final String defaultJavaTemplateDir = ".." + Utils.fileSeparator + "templ.java";
+ private enum GeneratorLangEnum { CPP, DOTNET, JAVA }
+
private DocumentBuilder docBuilder;
private AmqpVersionSet versionSet;
private Generator generator;
@@ -49,7 +52,7 @@ public class Main
private String outDir;
private String tmplDir;
- private boolean javaFlag;
+ private GeneratorLangEnum generatorLang;
private ArrayList<String> xmlFiles;
private File[] modelTemplateFiles;
private File[] classTemplateFiles;
@@ -81,13 +84,20 @@ public class Main
// 0. Initialize
outDir = defaultOutDir;
tmplDir = null;
- javaFlag = true;
+ generatorLang = GeneratorLangEnum.CPP; // Default generation language
xmlFiles.clear();
processArgs(args);
- if (javaFlag)
- prepareJava();
- else
+ switch (generatorLang)
+ {
+ case JAVA:
+ prepareJava();
+ break;
+ case DOTNET:
+ prepareDotnet();
+ break;
+ default:
prepareCpp();
+ }
if (modelTemplateFiles.length == 0 && classTemplateFiles.length == 0 &&
methodTemplateFiles.length == 0 && fieldTemplateFiles.length == 0)
@@ -128,11 +138,15 @@ public class Main
{
case 'c':
case 'C':
- javaFlag = false;
+ generatorLang = GeneratorLangEnum.CPP;
break;
case 'j':
case 'J':
- javaFlag = true;
+ generatorLang = GeneratorLangEnum.JAVA;
+ break;
+ case 'n':
+ case 'N':
+ generatorLang = GeneratorLangEnum.DOTNET;
break;
case 'o':
case 'O':
@@ -182,6 +196,30 @@ public class Main
};
}
+ private void prepareDotnet()
+ {
+ if (tmplDir == null)
+ tmplDir = defaultDotnetTemplateDir;
+ System.out.println(".NET generation mode.");
+ generator = new DotnetGenerator(versionSet);
+ constants = new AmqpConstantSet(generator);
+ domainMap = new AmqpDomainMap(generator);
+ model = new AmqpModel(generator);
+ // TODO: Add templated that should be handled in here...
+ modelTemplateFiles = new File[]
+ {
+// new File(tmplDir + Utils.fileSeparator + "XXXClass.tmpl"),
+ };
+ classTemplateFiles = new File[]
+ {
+// new File(tmplDir + Utils.fileSeparator + "XXXClass.tmpl"),
+ };
+ methodTemplateFiles = new File[]
+ {
+// new File(tmplDir + Utils.fileSeparator + "XXXClass.tmpl"),
+ };
+ }
+
private void prepareCpp()
{
if (tmplDir == null)
@@ -293,6 +331,7 @@ public class Main
System.out.println("Usage: Main -c|-j [-o outDir] [-t tmplDir] XMLfile [XMLfile ...]");
System.out.println(" where -c: Generate C++.");
System.out.println(" -j: Generate Java.");
+ System.out.println(" -n: Generate .NET.");
System.out.println(" -o outDir: Use outDir as the output dir (default=\"" + defaultOutDir + "\").");
System.out.println(" -t tmplDir: Find templates in tmplDir.");
System.out.println(" Defaults: \"" + defaultCppTemplateDir + "\" for C++;");