diff options
Diffstat (limited to 'gentools/src')
| -rw-r--r-- | gentools/src/org/apache/qpid/gentools/DotnetGenerator.java | 319 | ||||
| -rw-r--r-- | gentools/src/org/apache/qpid/gentools/JavaGenerator.java | 2 | ||||
| -rw-r--r-- | gentools/src/org/apache/qpid/gentools/Main.java | 53 |
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++;"); |
