summaryrefslogtreecommitdiff
path: root/gentools
diff options
context:
space:
mode:
authorKim van der Riet <kpvdr@apache.org>2007-01-16 19:53:55 +0000
committerKim van der Riet <kpvdr@apache.org>2007-01-16 19:53:55 +0000
commit8665f60c71942e4ba29ffec829301e63f29da203 (patch)
tree15ebb31883e06edfab0639f739ef204a0269066d /gentools
parente5147d0df8b76db94059a442cfbe40cbce22d79f (diff)
downloadqpid-python-8665f60c71942e4ba29ffec829301e63f29da203.tar.gz
Added .NET generator class to the code generator, and added mechanism to invoke it from the command line. The DotnetGenerator class is still mostly empty (ie has no code generation methods). The next step is to plan the templates that are required for .NET, and then implement them alongside the generator class code snippet methods.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@496841 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'gentools')
-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++;");