Author: kpvdr
Date: Wed Nov 1 07:20:01 2006
New Revision: 469929
URL: http://svn.apache.org/viewvc?view=rev&rev=469929
Log:
Updated code generator to produce ServerOperations class. Other minor fixes in
generator.
Added:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
Modified:
incubator/qpid/trunk/qpid/gentools/README
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/Generator.java
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java
incubator/qpid/trunk/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl
Modified: incubator/qpid/trunk/qpid/gentools/README
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/README?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
--- incubator/qpid/trunk/qpid/gentools/README (original)
+++ incubator/qpid/trunk/qpid/gentools/README Wed Nov 1 07:20:01 2006
@@ -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
Modified:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
--- incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java
(original)
+++ incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpMethod.java
Wed Nov 1 07:20:01 2006
@@ -135,6 +135,32 @@
}
}
+ 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))
Modified:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
---
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
(original)
+++
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
Wed Nov 1 07:20:01 2006
@@ -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;
+ }
}
Added:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java?view=auto&rev=469929
==============================================================================
---
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
(added)
+++
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
Wed Nov 1 07:20:01 2006
@@ -0,0 +1,9 @@
+package org.apache.qpid.gentools;
+
+import java.util.TreeMap;
+
[EMAIL PROTECTED]("serial")
+public class AmqpOverloadedParameterMap extends TreeMap<AmqpOrdinalFieldMap,
AmqpVersionSet>
+{
+
+}
Modified:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
---
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java
(original)
+++
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/CppGenerator.java
Wed Nov 1 07:20:01 2006
@@ -20,7 +20,6 @@
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 @@
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 @@
}
@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 @@
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 @@
}
// === 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())
@@ -759,6 +891,20 @@
// }
// 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)
{
Modified:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/Generator.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/Generator.java?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
--- incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/Generator.java
(original)
+++ incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/Generator.java
Wed Nov 1 07:20:01 2006
@@ -136,10 +136,10 @@
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)
Modified:
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
---
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java
(original)
+++
incubator/qpid/trunk/qpid/gentools/org/apache/qpid/gentools/JavaGenerator.java
Wed Nov 1 07:20:01 2006
@@ -472,7 +472,7 @@
@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 @@
@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
Modified:
incubator/qpid/trunk/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl
URL:
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl?view=diff&rev=469929&r1=469928&r2=469929
==============================================================================
--- incubator/qpid/trunk/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl
(original)
+++ incubator/qpid/trunk/qpid/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl
Wed Nov 1 07:20:01 2006
@@ -34,16 +34,27 @@
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 */