diff options
author | Kim van der Riet <kpvdr@apache.org> | 2006-11-01 15:20:01 +0000 |
---|---|---|
committer | Kim van der Riet <kpvdr@apache.org> | 2006-11-01 15:20:01 +0000 |
commit | 28c8fafb1922af27189759cae2b7463df08c45c7 (patch) | |
tree | 20a692025e323c7e2d4155fd425235d7f5fbff09 /qpid | |
parent | 4860a3e0de89f2d53d444e05a435901041913ed5 (diff) | |
download | qpid-python-28c8fafb1922af27189759cae2b7463df08c45c7.tar.gz |
Updated code generator to produce ServerOperations class. Other minor fixes in generator.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@469929 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid')
8 files changed, 284 insertions, 33 deletions
diff --git a/qpid/gentools/README b/qpid/gentools/README index 12bfd10caf..08df62948d 100644 --- a/qpid/gentools/README +++ b/qpid/gentools/README @@ -1,28 +1,41 @@ AMQP MULTI_VERSION CODE GENERATOR -This directory contains the first part of the new multi-AMQP-version code generator. The Java generation is almost complete, C++ will follow. +This directory contains the first part of the new multi-AMQP-version code +generator. The Java generation is almost complete, C++ will follow. -NOTE: The generator has NOT been integrated into the current build, and is included here to run stand-alone for the purposes of review and comment. As currently configured, this generator will not interact with any file or directory outside of this directory. +NOTE: The generator has NOT been integrated into the current build, and is +included here to run stand-alone for the purposes of review and comment. As +currently configured, this generator will not interact with any file or +directory outside of this directory. To build (from this directory): javac org/apache/qpid/gentools/Main.java +Make sure you are using Sun's JDK1.5.0; Eclipse and gcj do not work. + To run (from this directory): java org/apache/qpid/gentools/Main -j [xml_spec_file, ...] -XML test files are located in the xml-src directory. Pay attention to the Basic class and Basic.Consume method - these were the primary test vehicles for this generator. *** NOTE *** These files do not represent any current or future version of the AMQP specification - do not use in production! +XML test files are located in the xml-src directory. Pay attention to the +Basic class and Basic.Consume method - these were the primary test vehicles +for this generator. *** NOTE *** These files do not represent any current or +future version of the AMQP specification - do not use in production! Folders: -------- org/apache/qpid/gentools/: Source. xml-src/: Test AMQP specification files. templ.java/: Templates for java code generation. -out.java/: Output folder for generated Java files (will be created with use of -j flag on command-line). +out.java/: Output folder for generated Java files (will be created with use + of -j flag on command-line). templ.cpp/: (Future:) Templates for C++ code generation. -out.cpp/: Output folder for generated C++ files (will be created with use of -c flag on command-line). +out.cpp/: Output folder for generated C++ files (will be created with use + of -c flag on command-line). -For a more detaild description of the generator, see the Qpid Wiki (http://cwiki.apache.org/qpid/multiple-amqp-version-support). +For a more detaild description of the generator, see the Qpid Wiki +(http://cwiki.apache.org/qpid/multiple-amqp-version-support.html). -Please send comments and bugs to me (kim.vdriet [at] redhat.com) or via the Apache Qpid list (qpid-dev [at] incubator.apache.org). +Please send comments and bugs to me (kim.vdriet [at] redhat.com) or via the +Apache Qpid list (qpid-dev [at] incubator.apache.org). Kim van der Riet diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java b/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java index 9dd4157a02..7ecb97530d 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java @@ -135,6 +135,32 @@ public class AmqpMethod implements Printable, NodeAware, VersionConsistencyCheck } } + public AmqpOverloadedParameterMap getOverloadedParameterLists(AmqpVersionSet globalVersionSet) + { + AmqpOverloadedParameterMap parameterVersionMap = new AmqpOverloadedParameterMap(); + Iterator<AmqpVersion> vItr = globalVersionSet.iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version); + if (ordinalFieldMap.size() > 0) + { + AmqpVersionSet methodVersionSet = parameterVersionMap.get(ordinalFieldMap); + if (methodVersionSet == null) + { + methodVersionSet = new AmqpVersionSet(); + methodVersionSet.add(version); + parameterVersionMap.put(ordinalFieldMap, methodVersionSet); + } + else + { + methodVersionSet.add(version); + } + } + } + return parameterVersionMap; + } + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) { if (!versionSet.equals(globalVersionSet)) diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java index 8eb4bfa57b..fd7ac239e7 100644 --- a/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java @@ -1,9 +1,55 @@ package org.apache.qpid.gentools; +import java.util.Iterator; +import java.util.Set; import java.util.TreeMap; @SuppressWarnings("serial") -public class AmqpOrdinalFieldMap extends TreeMap<Integer, String[]> +public class AmqpOrdinalFieldMap extends TreeMap<Integer, String[]> implements Comparable { - + public int compareTo(Object obj) + { + AmqpOrdinalFieldMap o = (AmqpOrdinalFieldMap)obj; + Set<Integer> thisKeySet = keySet(); + Set<Integer> oKeySet = o.keySet(); + if (!thisKeySet.equals(oKeySet)) // Not equal, but why? + { + // Size difference + int sizeDiff = thisKeySet.size() - oKeySet.size(); // -ve if this < other + if (sizeDiff != 0) + return sizeDiff; + // Conetent difference + Iterator<Integer> itr = thisKeySet.iterator(); + Iterator<Integer> oItr = oKeySet.iterator(); + while (itr.hasNext() && oItr.hasNext()) + { + int diff = itr.next() - oItr.next(); // -ve if this < other + if (diff != 0) + return diff; + } + // We should never get here... + System.err.println("AmqpOrdinalFieldMap.compareTo(): " + + "WARNING - unable to find cause of keySet difference."); + } + // Keys are equal, now check the String[]s + Iterator<Integer> itr = thisKeySet.iterator(); + Iterator<Integer> oItr = oKeySet.iterator(); + while (itr.hasNext() && oItr.hasNext()) + { + String[] thisPair = get(itr.next()); + String[] oPair = o.get(oItr.next()); + // Size difference + int sizeDiff = thisPair.length - oPair.length; // -ve if this < other + if (sizeDiff != 0) + return sizeDiff; + // Conetent difference + for (int i=0; i<thisPair.length; i++) + { + int diff = thisPair[i].compareTo(oPair[i]); + if (diff != 0) + return diff; + } + } + return 0; + } } diff --git a/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java b/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java new file mode 100644 index 0000000000..631118301b --- /dev/null +++ b/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java @@ -0,0 +1,9 @@ +package org.apache.qpid.gentools; + +import java.util.TreeMap; + +@SuppressWarnings("serial") +public class AmqpOverloadedParameterMap extends TreeMap<AmqpOrdinalFieldMap, AmqpVersionSet> +{ + +} diff --git a/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java b/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java index 3bd7687057..d15d1b2d06 100644 --- a/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java +++ b/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java @@ -20,7 +20,6 @@ package org.apache.qpid.gentools; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.TreeMap; @@ -32,9 +31,17 @@ public class CppGenerator extends Generator protected static final String versionNamespaceEndToken = "${version_namespace_end}"; protected static final int FIELD_NAME = 0; protected static final int FIELD_DOMAIN = 1; - + protected static final String[] cppReservedWords = {"and", "and_eq", "asm", "auto", "bitand", + "bitor", "bool", "break", "case", "catch", "char", "class", "compl", "const", "const_cast", + "continue", "default", "delete", "do", "DomainInfo", "double", "dynamic_cast", "else", + "enum", "explicit", "extern", "false", "float", "for", "friend", "goto", "if", "inline", + "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq", + "private", "protected", "public", "register", "reinterpret_cast", "return", "short", + "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", "this", + "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", + "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"}; - private class DomainInfo + private class DomainInfo { public String type; public String size; @@ -294,15 +301,37 @@ public class CppGenerator extends Generator } @Override - protected void processClassList(StringBuffer sb, int tokStart, int tokEnd, AmqpModel model) - throws AmqpTemplateException + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model) + throws AmqpTemplateException, AmqpTypeMappingException { -// TODO + 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 tokxStart = tline.indexOf('$'); + String token = tline.substring(tokxStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + if (token.compareTo("${co_method_handler_get_method}") == 0) + { + codeSnippet = generateMethodHandlerGetMethods(model, 8); + } + else if (token.compareTo("${co_server_method_inner_class}") == 0) + { + codeSnippet = generateInnerClasses(model, 8, 4); + } + + else // Oops! + { + throw new AmqpTemplateException("Template token \"" + token + "\" unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); } @Override - protected void processMethodList(StringBuffer sb, int tokStart, int tokEnd, AmqpClass thisClass) - throws AmqpTemplateException + protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpClass thisClass) + throws AmqpTemplateException, AmqpTypeMappingException { // TODO } @@ -320,7 +349,6 @@ public class CppGenerator extends Generator String token = tline.substring(tokxStart).trim(); sb.delete(listMarkerStartIndex, lend); - // Field declarations - common to MethodBody and PropertyContentHeader classes if (token.compareTo("${mb_field_declaration}") == 0) { codeSnippet = generateFieldDeclarations(fieldMap, version, 4); @@ -366,13 +394,117 @@ public class CppGenerator extends Generator } // === Protected and private helper functions unique to C++ implementation === - - // Methods used for generation of code snippets called from the field map parsers - - // Common methods + + // Methods used for generation of code snippets for ServerOperations class generation + + protected String generateMethodHandlerGetMethods(AmqpModel model, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + Iterator<String> cItr = model.classMap.keySet().iterator(); + while (cItr.hasNext()) + { + AmqpClass thisClass = model.classMap.get(cItr.next()); + sb.append(indent + "virtual AMQP_ServerOperations::" + + thisClass.name + "Handler* get" + thisClass.name + "Handler() = 0;" + cr); + } + return sb.toString(); + } + + protected String generateInnerClasses(AmqpModel model, int indentSize, int tabSize) + throws AmqpTypeMappingException + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + Iterator<String> cItr = model.classMap.keySet().iterator(); + while (cItr.hasNext()) + { + AmqpClass thisClass = model.classMap.get(cItr.next()); + String className = thisClass.name + "Handler"; + if (!first) + sb.append(cr); + sb.append(indent + "class " + className); + if (thisClass.versionSet.size() != globalVersionSet.size()) + sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); + else + sb.append(cr); + sb.append(indent + "{" + cr); + sb.append(indent + "private:" + cr); + sb.append(indent + tab + "u_int8_t major;" + cr); + sb.append(indent + tab + "u_int8_t minor;" + cr); + sb.append(cr); + sb.append(indent + "public:" + cr); + sb.append(indent + tab + "// Constructors and destructors" + cr); + sb.append(cr); + sb.append(indent + tab + className + + "(u_int8_t major, u_int8_t minor) : major(major), minor(minor) {}" + cr); + sb.append(indent + tab + "virtual ~" + className + "() {}" + cr); + sb.append(cr); + sb.append(indent + tab + "// Protocol methods" + cr); + sb.append(cr); + sb.append(generateInnerClassMethods(thisClass, indentSize + tabSize, tabSize)); + sb.append(indent + "}; // class " + className + cr); + first = false; + } + return sb.toString(); + } + + protected String generateInnerClassMethods(AmqpClass thisClass, int indentSize, int tabSize) + throws AmqpTypeMappingException + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + Iterator<String> mItr = thisClass.methodMap.keySet().iterator(); + while (mItr.hasNext()) + { + AmqpMethod method = thisClass.methodMap.get(mItr.next()); + AmqpOverloadedParameterMap overloadededParameterMap = method.getOverloadedParameterLists(globalVersionSet); + Iterator<AmqpOrdinalFieldMap> ofmItr = overloadededParameterMap.keySet().iterator(); + String methodName = parseForReservedWords(method.name, thisClass.name); + while (ofmItr.hasNext()) + { + AmqpOrdinalFieldMap fieldMap = ofmItr.next(); + AmqpVersionSet versionSet = overloadededParameterMap.get(fieldMap); + if (!first) + sb.append(cr); + sb.append(indent + "virtual void " + methodName + "("); + sb.append(generateMethodParameterList(fieldMap, indentSize + (5*tabSize))); + if (versionSet.size() != globalVersionSet.size()) + sb.append(") = 0; // AMQP Version(s) " + versionSet + cr); + else + sb.append(") = 0;" + cr); + first = false; + } + } + return sb.toString(); + } + + protected String generateMethodParameterList(AmqpOrdinalFieldMap fieldMap, int indentSize) + throws AmqpTypeMappingException + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + Iterator<Integer> pItr = fieldMap.keySet().iterator(); + while(pItr.hasNext()) + { + String[] field = fieldMap.get(pItr.next()); + String codeType = getGeneratedType(field[FIELD_DOMAIN], globalVersionSet.first()); + if (!first) + sb.append(indent); + sb.append(setRef(codeType) + " " + field[FIELD_NAME] + (pItr.hasNext() ? "," + cr : "")); + first = false; + } + return sb.toString(); + } + + // Methods used for generation of code snippets for MethodBody class generation protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) - throws AmqpTemplateException + throws AmqpTemplateException { Iterator<Integer> iItr = indexMap.keySet().iterator(); while (iItr.hasNext()) @@ -760,6 +892,20 @@ public class CppGenerator extends Generator // return sb.toString(); // } + private String parseForReservedWords(String methodName, String className) + { + for (int i=0; i<cppReservedWords.length; i++) + if (methodName.compareTo(cppReservedWords[i]) == 0) + { + System.err.println("WARNING: Found method \"" + methodName + + "\" in class \"" + className + + "\", which is a C/C++ reserved word. " + + "Changing generated method name to \"" + methodName + "_\"."); + return methodName + "_"; + } + return methodName; + } + private String setRef(String codeType) { if (codeType.compareTo("string") == 0 || diff --git a/qpid/gentools/org/apache/qpid/gentools/Generator.java b/qpid/gentools/org/apache/qpid/gentools/Generator.java index 23f019283b..76f78ebb41 100644 --- a/qpid/gentools/org/apache/qpid/gentools/Generator.java +++ b/qpid/gentools/org/apache/qpid/gentools/Generator.java @@ -136,10 +136,10 @@ public abstract class Generator implements LanguageConverter throws AmqpTemplateException; abstract protected void processClassList(StringBuffer sb, int tokStart, int tokEnd, AmqpModel model) - throws AmqpTemplateException; + throws AmqpTemplateException, AmqpTypeMappingException; abstract protected void processMethodList(StringBuffer sb, int tokStart, int tokEnd, AmqpClass thisClass) - throws AmqpTemplateException; + throws AmqpTemplateException, AmqpTypeMappingException; abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version) diff --git a/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java b/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java index 5d92a66671..82eb97ac6f 100644 --- a/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java +++ b/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java @@ -472,7 +472,7 @@ public class JavaGenerator extends Generator @Override protected void processClassList(StringBuffer sb, int tokStart, int tokEnd, AmqpModel model) - throws AmqpTemplateException + throws AmqpTemplateException, AmqpTypeMappingException { String codeSnippet; int lend = sb.indexOf(cr, tokStart) + 1; // Include cr at end of line @@ -496,7 +496,7 @@ public class JavaGenerator extends Generator @Override protected void processMethodList(StringBuffer sb, int tokStart, int tokEnd, AmqpClass thisClass) - throws AmqpTemplateException + throws AmqpTemplateException, AmqpTypeMappingException { String codeSnippet; int lend = sb.indexOf(cr, tokStart) + 1; // Include cr at end of line diff --git a/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl b/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl index 26c06d42a2..80c6c0f5ab 100644 --- a/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl +++ b/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl @@ -34,16 +34,27 @@ namespace framing { class AMQP_ServerOperations { + private: + u_int8_t major; + u_int8_t minor; public: - AMQP_ServerOperations() {} + AMQP_ServerOperations(u_int8_t major, u_int8_t minor) : major(major), minor(minor) {} virtual ~AMQP_ServerOperations() {} -{so_get_amqp_major} -{so_get_amqp_minor} + + inline u_int8_t getMajor() { return major; } + inline u_int8_t getMinor() { return minor; } + inline isVersion(u_int8_t _major, u_int8_t _minor) + { + return major == _major && minor == _minor; + } - // Method handler get methods -{CLIST} {co_method_handler_get_method} + // Method handler get methods + +%{CLIST} ${co_method_handler_get_method} -{CLIST} {co_server_method_inner_class} + // Inner classes + +%{CLIST} ${co_server_method_inner_class} }; /* class AMQP_ServerOperations */ |