summaryrefslogtreecommitdiff
path: root/qpid/gentools
diff options
context:
space:
mode:
authorKim van der Riet <kpvdr@apache.org>2006-11-01 15:20:01 +0000
committerKim van der Riet <kpvdr@apache.org>2006-11-01 15:20:01 +0000
commit28c8fafb1922af27189759cae2b7463df08c45c7 (patch)
tree20a692025e323c7e2d4155fd425235d7f5fbff09 /qpid/gentools
parent4860a3e0de89f2d53d444e05a435901041913ed5 (diff)
downloadqpid-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/gentools')
-rw-r--r--qpid/gentools/README27
-rw-r--r--qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java26
-rw-r--r--qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java50
-rw-r--r--qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java9
-rw-r--r--qpid/gentools/org/apache/qpid/gentools/CppGenerator.java174
-rw-r--r--qpid/gentools/org/apache/qpid/gentools/Generator.java4
-rw-r--r--qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java4
-rw-r--r--qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl23
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 */