diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2007-11-24 21:14:14 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2007-11-24 21:14:14 +0000 |
commit | 66f97f32c78e0cf5914a441ae8277ee3aa659ce9 (patch) | |
tree | f825c3d20483f741c06b9584ddb4e17d6a2404a9 | |
parent | 86996d5680a07acd82ffda2829dcdd6d6585e606 (diff) | |
download | qpid-python-66f97f32c78e0cf5914a441ae8277ee3aa659ce9.tar.gz |
QPID-567 : Add mutliversion support to Qpid/Java.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/M2.1@597918 13f79535-47bb-0310-9956-ffa450edef68
166 files changed, 12373 insertions, 6638 deletions
diff --git a/gentools/build.xml b/gentools/build.xml index d35790f714..6006c2bcf8 100644 --- a/gentools/build.xml +++ b/gentools/build.xml @@ -22,7 +22,14 @@ <property name="src" location="src" /> <target name="compile"> - <javac srcdir="${src}" source="1.5" fork="true" debug="on"/> + <javac srcdir="${src}" source="1.5" fork="true" debug="on"> + <classpath> + <fileset dir="${src}/../lib"> + <include name="**/*.jar"/> + </fileset> + </classpath> + + </javac> </target> <target name="clean"> diff --git a/gentools/lib/LICENSE b/gentools/lib/LICENSE new file mode 100644 index 0000000000..43fa6abd19 --- /dev/null +++ b/gentools/lib/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/gentools/lib/NOTICE b/gentools/lib/NOTICE new file mode 100644 index 0000000000..09e9ae4902 --- /dev/null +++ b/gentools/lib/NOTICE @@ -0,0 +1,2 @@ +This product includes software developed by The Apache Software Foundation (http://www.apache.org/). + diff --git a/gentools/lib/README.txt b/gentools/lib/README.txt new file mode 100644 index 0000000000..eb364ece53 --- /dev/null +++ b/gentools/lib/README.txt @@ -0,0 +1,102 @@ +--------
+Velocity
+--------
+
+Welcome to Velocity. Velocity is a general purpose template engine
+written in Java. For more information about Velocity, please look at the
+HTML documentation in the docs/ directory, as well as the Velocity
+web site
+
+ http://jakarta.apache.org/velocity/index.html
+
+Here is a description of what each of the top level directories
+contains. Please consult the documentation in each of the lower level
+directories for information that is specific to their contents.
+
+bin/ This is a temporary build directory.
+build/ This is where the build scripts live.
+docs/ This is where the documentation lives.
+examples/ This is where the examples live.
+src/ This is where all of the source code to Velocity lives.
+test/ This is where all of the tests live.
+xdocs/ This is the .xml files for building the .html files
+ related to the website and documentation.
+
+REQUIREMENTS
+------------
+
+The Java 2 SDK is required to build Velocity.
+
+For users that wish to use Log4J as the logging
+system, version 1.1 or newer of Log4J is required.
+
+
+INCLUDED PRE-BUILT JARS
+-----------------------
+If you are using an offical Velocity release distribution,
+you will find two pre-built Velocity jars in the top level
+directory.
+
+PLEASE NOTE : Starting with the 1.2 release, we include two jars
+ with the distribution.
+
+1) velocity-<version>.jar : The Velocity jar that does not include
+any external dependencies needed by Velocity, such as the
+jakarta-commons-collection classes, Jakarta Avalon Logkit, or
+Jakarta ORO. We do this to allow you to use whatever version of
+collections, logkit, etc that you wish w/o fear of collision.
+These jars are included in the distribution, in
+the build/lib directory, or at the respective project sites.
+
+2) velocity-dep-<version>.jar : This is a Velocity jar that includes
+all dependencies that were included with previous distribution
+jars. It is intended as a convenience to allow you to drop
+this 1.3 (or later) distribution in place of existing 1.1 or 1.2-dep
+ distributions.
+
+Please see the developers guide for more information.
+
+BUILDING VELOCITY
+-----------------
+
+In order to get started with Velocity, you may want to build it.
+
+Building Velocity is easy. All components necessary to build Velocity are
+included, except for the Java 2 SDK and the fabulous Ant build tool
+from the Jakarta project.
+
+http://jakarta.apache.org/ant/
+
+Note that you must use Ant version 1.4 or later.
+
+To build Velocity's jar, change directory into the build/ directory and
+simply type :
+
+ant jar
+
+This will create a bin/ directory containing the Velocity .jar file. Be
+sure to update your classpath to include Velocity's .jar file, or when using a
+modern servlet container, put it in the WEB-INF/lib directory.
+
+If you wish to build a Velocity jar that contains all dependencies, we have
+provided an optional build target for our convenience :
+
+ant jar-dep
+
+This will build a complete Velocity jar with dependencies included, and it can
+be found in the /bin directory as
+
+velocity-dep-<version>.jar
+
+TRYING THE EXAMPLES
+-------------------
+
+After building Velocity, you can also buld the examples that are included
+with the Velocity distribution. These examples show how to use Velocity
+in your Java applications and Servlets. There also are examples of
+how to use Anakia, a XML transformation engine and an example of a servlet-
+based forum application.
+
+For more information, please see the README.txt in the examples/ directory.
+
+-The Velocity Team
diff --git a/gentools/lib/velocity-1.4.jar b/gentools/lib/velocity-1.4.jar Binary files differnew file mode 100644 index 0000000000..04ec9d2f85 --- /dev/null +++ b/gentools/lib/velocity-1.4.jar diff --git a/gentools/lib/velocity-dep-1.4.jar b/gentools/lib/velocity-dep-1.4.jar Binary files differnew file mode 100644 index 0000000000..375712b0e8 --- /dev/null +++ b/gentools/lib/velocity-dep-1.4.jar diff --git a/gentools/src/org/apache/qpid/gentools/AmqpClass.java b/gentools/src/org/apache/qpid/gentools/AmqpClass.java index 2e8bdaf971..e79688b28f 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpClass.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpClass.java @@ -20,129 +20,180 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; -public class AmqpClass implements Printable, NodeAware +import java.io.PrintStream; +import java.util.Collection; + +public class AmqpClass implements Printable, NodeAware { - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpFieldMap fieldMap; - public AmqpMethodMap methodMap; - public String name; - public AmqpOrdinalVersionMap indexMap; - - public AmqpClass(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - fieldMap = new AmqpFieldMap(); - methodMap = new AmqpMethodMap(); - indexMap = new AmqpOrdinalVersionMap(); - } - - public boolean addFromNode(Node classNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - int index = Utils.getNamedIntegerAttribute(classNode, "index"); - AmqpVersionSet indexVersionSet = indexMap.get(index); - if (indexVersionSet != null) - indexVersionSet.add(version); - else - { - indexVersionSet = new AmqpVersionSet(); - indexVersionSet.add(version); - indexMap.put(index, indexVersionSet); - } - NodeList nList = classNode.getChildNodes(); - int fieldCntr = fieldMap.size(); - for (int i=0; i<nList.getLength(); i++) - { - Node child = nList.item(i); - if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) - { - String fieldName = converter.prepareDomainName(Utils.getNamedAttribute(child, - Utils.ATTRIBUTE_NAME)); - AmqpField thisField = fieldMap.get(fieldName); - if (thisField == null) - { - thisField = new AmqpField(fieldName, converter); - fieldMap.put(fieldName, thisField); - } - if (!thisField.addFromNode(child, fieldCntr++, version)) - { - String className = converter.prepareClassName(Utils.getNamedAttribute(classNode, - Utils.ATTRIBUTE_NAME)); - System.out.println("INFO: Generation supression tag found for field " + - className + "." + fieldName + " - removing."); - thisField.removeVersion(version); - fieldMap.remove(fieldName); - } - } - else if (child.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0) - { - String methodName = converter.prepareMethodName(Utils.getNamedAttribute(child, - Utils.ATTRIBUTE_NAME)); - AmqpMethod thisMethod = methodMap.get(methodName); - if (thisMethod == null) - { - thisMethod = new AmqpMethod(methodName, converter); - methodMap.put(methodName, thisMethod); - } - if (!thisMethod.addFromNode(child, 0, version)) - { - String className = converter.prepareClassName(Utils.getNamedAttribute(classNode, - Utils.ATTRIBUTE_NAME)); - System.out.println("INFO: Generation supression tag found for method " + - className + "." + methodName + " - removing."); - thisMethod.removeVersion(version); - methodMap.remove(methodName); - } - } - else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) - { - String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); - if (value.compareTo("no-gen") == 0) - return false; - } - } - return true; - } - - public void removeVersion(AmqpVersion version) - { - indexMap.removeVersion(version); - fieldMap.removeVersion(version); - methodMap.removeVersion(version); - versionSet.remove(version); - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - String margin = Utils.createSpaces(marginSize); - String tab = Utils.createSpaces(tabSize); - out.println(margin + "[C] " + name + ": " + versionSet); - - for (Integer thisIndex : indexMap.keySet()) - { - AmqpVersionSet indexVersionSet = indexMap.get(thisIndex); - out.println(margin + tab + "[I] " + thisIndex + indexVersionSet); - } - - for (String thisFieldName : fieldMap.keySet()) - { - AmqpField thisField = fieldMap.get(thisFieldName); - thisField.print(out, marginSize + tabSize, tabSize); - } - - for (String thisMethodName : methodMap.keySet()) - { - AmqpMethod thisMethod = methodMap.get(thisMethodName); - thisMethod.print(out, marginSize + tabSize, tabSize); - } - } + + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + private final AmqpFieldMap _fieldMap = new AmqpFieldMap(); + private final AmqpMethodMap _methodMap = new AmqpMethodMap(); + private final AmqpOrdinalVersionMap _indexMap = new AmqpOrdinalVersionMap(); + + + private final String _name; + private final Generator _generator; + + public AmqpClass(String name, Generator generator) + { + _name = name; + _generator = generator; + } + + public boolean addFromNode(Node classNode, int ordinal, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + getVersionSet().add(version); + int index = Utils.getNamedIntegerAttribute(classNode, "index"); + AmqpVersionSet indexVersionSet = getIndexMap().get(index); + if (indexVersionSet != null) + { + indexVersionSet.add(version); + } + else + { + indexVersionSet = new AmqpVersionSet(); + indexVersionSet.add(version); + getIndexMap().put(index, indexVersionSet); + } + NodeList nList = classNode.getChildNodes(); + int fieldCntr = getFieldMap().size(); + for (int i = 0; i < nList.getLength(); i++) + { + Node child = nList.item(i); + if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) + { + String fieldName = getGenerator().prepareDomainName(Utils.getNamedAttribute(child, + Utils.ATTRIBUTE_NAME)); + AmqpField thisField = getFieldMap().get(fieldName); + if (thisField == null) + { + thisField = new AmqpField(fieldName, getGenerator()); + getFieldMap().add(fieldName, thisField); + } + if (!thisField.addFromNode(child, fieldCntr++, version)) + { + String className = getGenerator().prepareClassName(Utils.getNamedAttribute(classNode, + Utils.ATTRIBUTE_NAME)); + System.out.println("INFO: Generation supression tag found for field " + + className + "." + fieldName + " - removing."); + thisField.removeVersion(version); + getFieldMap().remove(fieldName); + } + } + else if (child.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0) + { + String methodName = getGenerator().prepareMethodName(Utils.getNamedAttribute(child, + Utils.ATTRIBUTE_NAME)); + AmqpMethod thisMethod = getMethodMap().get(methodName); + if (thisMethod == null) + { + thisMethod = new AmqpMethod(methodName, getGenerator()); + getMethodMap().put(methodName, thisMethod); + } + if (!thisMethod.addFromNode(child, 0, version)) + { + String className = getGenerator().prepareClassName(Utils.getNamedAttribute(classNode, + Utils.ATTRIBUTE_NAME)); + System.out.println("INFO: Generation supression tag found for method " + + className + "." + methodName + " - removing."); + thisMethod.removeVersion(version); + getMethodMap().remove(methodName); + } + } + else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) + { + String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); + if (value.compareTo("no-gen") == 0) + { + return false; + } + } + } + return true; + } + + public void removeVersion(AmqpVersion version) + { + getIndexMap().removeVersion(version); + getFieldMap().removeVersion(version); + getMethodMap().removeVersion(version); + getVersionSet().remove(version); + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + String tab = Utils.createSpaces(tabSize); + out.println(margin + "[C] " + getName() + ": " + getVersionSet()); + + for (Integer thisIndex : getIndexMap().keySet()) + { + AmqpVersionSet indexVersionSet = getIndexMap().get(thisIndex); + out.println(margin + tab + "[I] " + thisIndex + indexVersionSet); + } + + for (String thisFieldName : getFieldMap().keySet()) + { + AmqpField thisField = getFieldMap().get(thisFieldName); + thisField.print(out, marginSize + tabSize, tabSize); + } + + for (String thisMethodName : getMethodMap().keySet()) + { + AmqpMethod thisMethod = getMethodMap().get(thisMethodName); + thisMethod.print(out, marginSize + tabSize, tabSize); + } + } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public Generator getGenerator() + { + return _generator; + } + + + public AmqpFieldMap getFieldMap() + { + return _fieldMap; + } + + + public AmqpMethodMap getMethodMap() + { + return _methodMap; + } + + public Collection<AmqpMethod> getMethods() + { + return getMethodMap().values(); + } + + + public String getName() + { + return _name; + } + + + public AmqpOrdinalVersionMap getIndexMap() + { + return _indexMap; + } + + public SingleVersionClass asSingleVersionClass(AmqpVersion version) + { + return new SingleVersionClass(this,version, _generator); + } + + + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java b/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java index 01d4df283b..a27a50d07e 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java @@ -25,5 +25,5 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpClassMap extends TreeMap<String, AmqpClass> { - + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpConstant.java b/gentools/src/org/apache/qpid/gentools/AmqpConstant.java index 6ccd2dbf99..df5bc6c362 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpConstant.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpConstant.java @@ -25,151 +25,134 @@ import java.util.TreeMap; /** * @author kpvdr - * Class to represent the <constant> declaration within the AMQP specification. - * Currently, only integer values exist within the specification, however looking forward - * to other possible types in the future, string and double types are also supported. - * - * The <constant> declaration in the specification contains only two attributes: - * name and value. - * - * The value of the constant is mapped against the version(s) for which the name is defined. - * This allows for a change in the value rather than the name only from one version to the next. + * Class to represent the <constant> declaration within the AMQP specification. + * Currently, only integer values exist within the specification, however looking forward + * to other possible types in the future, string and double types are also supported. + * <p/> + * The <constant> declaration in the specification contains only two attributes: + * name and value. + * <p/> + * The value of the constant is mapped against the version(s) for which the name is defined. + * This allows for a change in the value rather than the name only from one version to the next. */ @SuppressWarnings("serial") public class AmqpConstant extends TreeMap<String, AmqpVersionSet> - implements Printable, VersionConsistencyCheck, Comparable<AmqpConstant> + implements Printable, VersionConsistencyCheck, Comparable<AmqpConstant> { /** * Constant name as defined by the name attribute of the <constant> declaration. */ - protected String name; - + private final String _name; + /** * Set of versions for which this constant name is defined. */ - protected AmqpVersionSet versionSet; + private final AmqpVersionSet _versionSet; /** * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. + * + * @param name Constant name as defined by the name attribute of the <constant> declaration. + * @param value Constant value as defined by the value attribute of the <constant> declaration. * @param version AMQP version for which this constant is defined */ - public AmqpConstant (String name, String value, AmqpVersion version) + public AmqpConstant(String name, String value, AmqpVersion version) { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); + _name = name; + _versionSet = new AmqpVersionSet(version); + AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); put(value, valueVersionSet); - } - - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, int value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(String.valueOf(value), valueVersionSet); } - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, double value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(String.valueOf(value), valueVersionSet); - } /** * Get the name of this constant. + * * @return Name of this constant, being the name attribute of the <constant> declaration - * represented by this class. + * represented by this class. */ public String getName() { - return name; + return _name; } - + /** * Get the value of this constant as a String. + * * @param version AMQP version for which this value is required. * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. + * represented by this class. * @throws AmqpTypeMappingException when a value is requested for a version for which it is not - * defined in the AMQP specifications. + * defined in the AMQP specifications. */ public String getStringValue(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { - for (String thisValue : keySet()) + for (String thisValue : keySet()) { AmqpVersionSet versionSet = get(thisValue); if (versionSet.contains(version)) + { return thisValue; + } } - throw new AmqpTypeMappingException("Unable to find value for constant \"" + name + - "\" for version " + version.toString() + "."); + throw new AmqpTypeMappingException("Unable to find value for constant \"" + getName() + + "\" for version " + version.toString() + "."); } - + /** * Get the value of this constant as an integer. + * * @param version AMQP version for which this value is required. * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. + * represented by this class. * @throws AmqpTypeMappingException when a value is requested for a version for which it is not - * defined in the AMQP specifications. + * defined in the AMQP specifications. */ public int getIntegerValue(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { return Integer.parseInt(getStringValue(version)); } - + /** * Get the value of this constant as a double. + * * @param version AMQP version for which this value is required. * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. + * represented by this class. * @throws AmqpTypeMappingException when a value is requested for a version for which it is not - * defined in the AMQP specifications. + * defined in the AMQP specifications. */ public double getDoubleValue(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { return Double.parseDouble(getStringValue(version)); } - + /** * Get the version set for this constant. It contains the all the versions for which this * constant name exists. + * * @return Set of versions for which this constant exists. */ public AmqpVersionSet getVersionSet() { - return versionSet; + return _versionSet; } - + /* (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(AmqpConstant other) { - int res = name.compareTo(other.name); + int res = getName().compareTo(other.getName()); if (res != 0) + { return res; - return versionSet.compareTo(other.versionSet); + } + return getVersionSet().compareTo(other.getVersionSet()); } /* (non-Javadoc) @@ -178,7 +161,9 @@ public class AmqpConstant extends TreeMap<String, AmqpVersionSet> public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) { if (size() != 1) + { return false; + } return get(firstKey()).equals(globalVersionSet); } @@ -191,15 +176,16 @@ public class AmqpConstant extends TreeMap<String, AmqpVersionSet> String tab = Utils.createSpaces(tabSize); if (size() == 1) { - out.println(margin + tab + "[C] " + name + " = \"" + firstKey() + "\" " + versionSet); + out.println(margin + tab + "[C] " + getName() + " = \"" + firstKey() + "\" " + getVersionSet()); } else { - out.println(margin + tab + "[C] " + name + ": " + versionSet); + out.println(margin + tab + "[C] " + getName() + ": " + getVersionSet()); for (String thisValue : keySet()) { - out.println(margin + tab + tab + "= \"" + thisValue + "\" " + get(thisValue)); + out.println(margin + tab + tab + "= \"" + thisValue + "\" " + get(thisValue)); } } } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java b/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java index 7b38f5cf3c..ab8b8be61e 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java @@ -20,55 +20,58 @@ */ package org.apache.qpid.gentools; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + import java.io.PrintStream; import java.util.Iterator; import java.util.TreeSet; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - /** * @author kpvdr - * This class implements a set collection for {@link #AmqpConstant AmqpConstant} objects, being the collection - * of constants accumulated from various AMQP specification files processed. Each name occurs once only in the set. - * The {@link #AmqpConstant AmqpConstant} objects (derived from {@link java.util#TreeMap TreeMap}) keep track of - * the value and version(s) assigned to this name. + * This class implements a set collection for {@link AmqpConstant AmqpConstant} objects, being the collection + * of constants accumulated from various AMQP specification files processed. Each name occurs once only in the set. + * The {@link AmqpConstant AmqpConstant} objects (derived from {@link java.util.TreeMap TreeMap}) keep track of + * the value and version(s) assigned to this name. */ @SuppressWarnings("serial") -public class AmqpConstantSet extends TreeSet<AmqpConstant> implements Printable, NodeAware, Comparable<AmqpConstantSet> +public class AmqpConstantSet implements Printable, NodeAware //, Comparable<AmqpConstantSet> { - public LanguageConverter converter; + private final LanguageConverter _converter; + private final TreeSet<AmqpConstant> _constants = new TreeSet<AmqpConstant>(); + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); public AmqpConstantSet(LanguageConverter converter) { - this.converter = converter; - this.converter.setConstantSet(this); + _converter = converter; + } - - /* (non-Javadoc) - * @see org.apache.qpid.gentools.NodeAware#addFromNode(org.w3c.dom.Node, int, org.apache.qpid.gentools.AmqpVersion) - */ + + /* (non-Javadoc) + * @see org.apache.qpid.gentools.NodeAware#addFromNode(org.w3c.dom.Node, int, org.apache.qpid.gentools.AmqpVersion) + */ public boolean addFromNode(Node node, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException + throws AmqpParseException, AmqpTypeMappingException { + _versionSet.add(version); NodeList nodeList = node.getChildNodes(); - for (int i=0; i<nodeList.getLength(); i++) + for (int i = 0; i < nodeList.getLength(); i++) { Node childNode = nodeList.item(i); if (childNode.getNodeName().compareTo(Utils.ELEMENT_CONSTANT) == 0) { - String name = converter.prepareDomainName(Utils.getNamedAttribute(childNode, Utils.ATTRIBUTE_NAME)); + String name = getConverter().prepareConstantName(Utils.getNamedAttribute(childNode, Utils.ATTRIBUTE_NAME)); String value = Utils.getNamedAttribute(childNode, Utils.ATTRIBUTE_VALUE); // Find this name in the existing set of objects boolean foundName = false; - Iterator<AmqpConstant> cItr = iterator(); + Iterator<AmqpConstant> cItr = _constants.iterator(); while (cItr.hasNext() && !foundName) { AmqpConstant thisConstant = cItr.next(); - if (name.compareTo(thisConstant.name) == 0) + if (name.compareTo(thisConstant.getName()) == 0) { foundName = true; - thisConstant.versionSet.add(version); + thisConstant.getVersionSet().add(version); // Now, find the value in the map boolean foundValue = false; for (String thisValue : thisConstant.keySet()) @@ -76,7 +79,7 @@ public class AmqpConstantSet extends TreeSet<AmqpConstant> implements Printable, if (value.compareTo(thisValue) == 0) { foundValue = true; - // Add this version to existing version set. + // Add this version to existing version set. AmqpVersionSet versionSet = thisConstant.get(thisValue); versionSet.add(version); } @@ -85,49 +88,65 @@ public class AmqpConstantSet extends TreeSet<AmqpConstant> implements Printable, if (!foundValue) { thisConstant.put(value, new AmqpVersionSet(version)); - } + } } } // Check that the name was found - if not, add it if (!foundName) { - add(new AmqpConstant(name, value, version)); + _constants.add(new AmqpConstant(name, value, version)); } - } + } } return true; } - + /* (non-Javadoc) - * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int) - */ + * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int) + */ public void print(PrintStream out, int marginSize, int tabSize) { out.println(Utils.createSpaces(marginSize) + "Constants: "); - for (AmqpConstant thisAmqpConstant : this) + for (AmqpConstant thisAmqpConstant : _constants) { - thisAmqpConstant.print(out, marginSize, tabSize); + thisAmqpConstant.print(out, marginSize, tabSize); } } - + /* (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public int compareTo(AmqpConstantSet other) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ +// public int compareTo(AmqpConstantSet other) +// { +// int res = size() - other.size(); +// if (res != 0) +// return res; +// Iterator<AmqpConstant> cItr = iterator(); +// Iterator<AmqpConstant> oItr = other.iterator(); +// while (cItr.hasNext() && oItr.hasNext()) +// { +// AmqpConstant constant = cItr.next(); +// AmqpConstant oConstant = oItr.next(); +// res = constant.compareTo(oConstant); +// if (res != 0) +// return res; +// } +// return 0; +// } + + public Iterable<? extends AmqpConstant> getContstants() { - int res = size() - other.size(); - if (res != 0) - return res; - Iterator<AmqpConstant> cItr = iterator(); - Iterator<AmqpConstant> oItr = other.iterator(); - while (cItr.hasNext() && oItr.hasNext()) - { - AmqpConstant constant = cItr.next(); - AmqpConstant oConstant = oItr.next(); - res = constant.compareTo(oConstant); - if (res != 0) - return res; - } - return 0; + return _constants; } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public LanguageConverter getConverter() + { + return _converter; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomain.java b/gentools/src/org/apache/qpid/gentools/AmqpDomain.java index 4796f31fb3..ba8552a6a6 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpDomain.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpDomain.java @@ -26,53 +26,64 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpDomain extends TreeMap<String, AmqpVersionSet> implements Printable { - public String domainName; + private final String _domainName; - public AmqpDomain(String domainName) - { - this.domainName = domainName; - } + public AmqpDomain(String domainName) + { + _domainName = domainName; + } - public void addDomain(String domainType, AmqpVersion version) throws AmqpParseException - { - AmqpVersionSet versionSet = get(domainType); - if (versionSet == null) // First time, create new entry - { - versionSet = new AmqpVersionSet(); - put(domainType, versionSet); - } - versionSet.add(version); - } + public void addDomain(String domainType, AmqpVersion version) throws AmqpParseException + { + AmqpVersionSet versionSet = get(domainType); + if (versionSet == null) // First time, create new entry + { + versionSet = new AmqpVersionSet(); + put(domainType, versionSet); + } + versionSet.add(version); + } + + public String getDomainType(AmqpVersion version) + throws AmqpTypeMappingException + { + for (String thisDomainType : keySet()) + { + AmqpVersionSet versionSet = get(thisDomainType); + if (versionSet.contains(version)) + { + return thisDomainType; + } + } + throw new AmqpTypeMappingException("Unable to find version " + version + "."); + } + + public boolean hasVersion(String type, AmqpVersion v) + { + AmqpVersionSet vs = get(type); + if (vs == null) + { + return false; + } + return vs.contains(v); + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + String tab = Utils.createSpaces(tabSize); + out.println(margin + getDomainName() + ":"); + + for (String thisDomainType : keySet()) + { + AmqpVersionSet vs = get(thisDomainType); + out.println(margin + tab + thisDomainType + " : " + vs.toString()); + } + } + + public String getDomainName() + { + return _domainName; + } - public String getDomainType(AmqpVersion version) - throws AmqpTypeMappingException - { - for (String thisDomainType : keySet()) - { - AmqpVersionSet versionSet = get(thisDomainType); - if (versionSet.contains(version)) - return thisDomainType; - } throw new AmqpTypeMappingException("Unable to find version " + version + "."); - } - - public boolean hasVersion(String type, AmqpVersion v) - { - AmqpVersionSet vs = get(type); - if (vs == null) - return false; - return vs.contains(v); - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - String margin = Utils.createSpaces(marginSize); - String tab = Utils.createSpaces(tabSize); - out.println(margin + domainName + ":"); - - for (String thisDomainType : keySet()) - { - AmqpVersionSet vs = get(thisDomainType); - out.println(margin + tab + thisDomainType + " : " + vs.toString()); - } - } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java b/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java index 7e2974a444..0cd9d214bd 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java @@ -20,100 +20,109 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; -import java.util.TreeMap; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.TreeMap; + @SuppressWarnings("serial") public class AmqpDomainMap extends TreeMap<String, AmqpDomain> implements Printable, NodeAware { - public LanguageConverter converter; + private final LanguageConverter _converter; - public AmqpDomainMap(LanguageConverter converter) - { - this.converter = converter; - this.converter.setDomainMap(this); - } - - public boolean addFromNode(Node n, int o, AmqpVersion v) - throws AmqpParseException, AmqpTypeMappingException - { - NodeList nl = n.getChildNodes(); - for (int i=0; i<nl.getLength(); i++) - { - Node c = nl.item(i); - // All versions 0.9 and greater use <domain> for all domains - if (c.getNodeName().compareTo(Utils.ELEMENT_DOMAIN) == 0) - { - String domainName = converter.prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); - String type = Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE); - AmqpDomain thisDomain = get(domainName); - if (thisDomain == null) - { - thisDomain = new AmqpDomain(domainName); - put(domainName, thisDomain); - } - thisDomain.addDomain(type, v); - } - // Version(s) 0.8 and earlier use <domain> for all complex domains and use - // attribute <field type=""...> for simple types. Add these simple types to - // domain list - but beware of duplicates! - else if (c.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) - { - try - { - String type = converter.prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE)); - AmqpDomain thisDomain = get(type); - if (thisDomain == null) - { - thisDomain = new AmqpDomain(type); - put(type, thisDomain); - } - if (!thisDomain.hasVersion(type, v)) - thisDomain.addDomain(type, v); - } - catch (AmqpParseException e) {} // Ignore fields without type attribute - } - else if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0 || - c.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0) - { - addFromNode(c, 0, v); - } - } - return true; - } + public AmqpDomainMap(LanguageConverter converter) + { + _converter = converter; - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - AmqpDomain domainType = get(domainName); - // For AMQP 8.0, primitive types were not described as domains, so - // return itself as the type. - if (domainType == null) - { - return domainName; - } - try - { - return domainType.getDomainType(version); - } - catch (AmqpTypeMappingException e) - { - throw new AmqpTypeMappingException("Unable to find domain type for domain \"" + domainName + - "\" version " + version + "."); - } - } - - - public void print(PrintStream out, int marginSize, int tabSize) - { + } + + public boolean addFromNode(Node n, int o, AmqpVersion v) + throws AmqpParseException, AmqpTypeMappingException + { + NodeList nl = n.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) + { + Node c = nl.item(i); + // All versions 0.9 and greater use <domain> for all domains + if (c.getNodeName().compareTo(Utils.ELEMENT_DOMAIN) == 0) + { + String domainName = getConverter().prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); + String type = Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE); + AmqpDomain thisDomain = get(domainName); + if (thisDomain == null) + { + thisDomain = new AmqpDomain(domainName); + put(domainName, thisDomain); + } + thisDomain.addDomain(type, v); + } + // Version(s) 0.8 and earlier use <domain> for all complex domains and use + // attribute <field type=""...> for simple types. Add these simple types to + // domain list - but beware of duplicates! + else if (c.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) + { + try + { + String type = getConverter().prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE)); + AmqpDomain thisDomain = get(type); + if (thisDomain == null) + { + thisDomain = new AmqpDomain(type); + put(type, thisDomain); + } + if (!thisDomain.hasVersion(type, v)) + { + thisDomain.addDomain(type, v); + } + } + catch (AmqpParseException e) + { + } // Ignore fields without type attribute + } + else if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0 || + c.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0) + { + addFromNode(c, 0, v); + } + } + return true; + } + + public String getDomainType(String domainName, AmqpVersion version) + { + AmqpDomain domainType = get(domainName); + // For AMQP 8.0, primitive types were not described as domains, so + // return itself as the type. + if (domainType == null) + { + return domainName; + } + try + { + return domainType.getDomainType(version); + } + catch (AmqpTypeMappingException e) + { + throw new AmqpTypeMappingException("Unable to find domain type for domain \"" + domainName + + "\" version " + version + "."); + } + } + + + public void print(PrintStream out, int marginSize, int tabSize) + { out.println(Utils.createSpaces(marginSize) + "Domain Map:"); for (String thisDomainName : keySet()) - { - AmqpDomain domain = get(thisDomainName); - domain.print(out, marginSize + tabSize, tabSize); - } - } + { + AmqpDomain domain = get(thisDomainName); + domain.print(out, marginSize + tabSize, tabSize); + } + } + + public LanguageConverter getConverter() + { + return _converter; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java b/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java index f91d98bfe7..e39550b96f 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java @@ -25,34 +25,38 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpDomainVersionMap extends TreeMap<String, AmqpVersionSet> implements VersionConsistencyCheck -{ - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (size() != 1) - return false; - return get(firstKey()).equals(globalVersionSet); - } - - public boolean removeVersion(AmqpVersion version) - { - Boolean res = false; - ArrayList<String> removeList = new ArrayList<String>(); - for (String domainName : keySet()) - { - AmqpVersionSet versionSet = get(domainName); - if (versionSet.contains(version)) - { - versionSet.remove(version); - if (versionSet.isEmpty()) - removeList.add(domainName); - res = true; - } - } - // Get rid of domains no longer in use - for (String domainName : removeList) - { - remove(domainName); - } - return res; - } +{ + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + { + return false; + } + return get(firstKey()).equals(globalVersionSet); + } + + public boolean removeVersion(AmqpVersion version) + { + Boolean res = false; + ArrayList<String> removeList = new ArrayList<String>(); + for (String domainName : keySet()) + { + AmqpVersionSet versionSet = get(domainName); + if (versionSet.contains(version)) + { + versionSet.remove(version); + if (versionSet.isEmpty()) + { + removeList.add(domainName); + } + res = true; + } + } + // Get rid of domains no longer in use + for (String domainName : removeList) + { + remove(domainName); + } + return res; + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpField.java b/gentools/src/org/apache/qpid/gentools/AmqpField.java index e1177e0154..7c721cf913 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpField.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpField.java @@ -20,137 +20,250 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; -import java.util.ArrayList; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + public class AmqpField implements Printable, NodeAware, VersionConsistencyCheck { - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpDomainVersionMap domainMap; - public AmqpOrdinalVersionMap ordinalMap; - public String name; - - public AmqpField(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - domainMap = new AmqpDomainVersionMap(); - ordinalMap = new AmqpOrdinalVersionMap(); - } - - public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - String domainType; - // Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields. - try - { - domainType = converter.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN)); - } - catch (AmqpParseException e) - { - domainType = converter.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE)); - } - AmqpVersionSet thisVersionList = domainMap.get(domainType); - if (thisVersionList == null) // First time, create new entry - { - thisVersionList = new AmqpVersionSet(); - domainMap.put(domainType, thisVersionList); - } - thisVersionList.add(version); - thisVersionList = ordinalMap.get(ordinal); - if (thisVersionList == null) // First time, create new entry - { - thisVersionList = new AmqpVersionSet(); - ordinalMap.put(ordinal, thisVersionList); - } - thisVersionList.add(version); - NodeList nList = fieldNode.getChildNodes(); - for (int i=0; i<nList.getLength(); i++) - { - Node child = nList.item(i); - if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) - { - String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); - if (value.compareTo("no-gen") == 0) - return false; - } - } - return true; - } - - public void removeVersion(AmqpVersion version) - { - domainMap.removeVersion(version); - ordinalMap.removeVersion(version); - versionSet.remove(version); - } - - public boolean isCodeTypeConsistent(LanguageConverter converter) - throws AmqpTypeMappingException - { - if (domainMap.size() == 1) - return true; // By definition - ArrayList<String> codeTypeList = new ArrayList<String>(); - for (String thisDomainName : domainMap.keySet()) - { - AmqpVersionSet versionSet = domainMap.get(thisDomainName); - String codeType = converter.getGeneratedType(thisDomainName, versionSet.first()); - if (!codeTypeList.contains(codeType)) - codeTypeList.add(codeType); - } - return codeTypeList.size() == 1; - } - - public boolean isConsistent(Generator generator) - throws AmqpTypeMappingException - { - if (!isCodeTypeConsistent(generator)) - return false; - if (ordinalMap.size() != 1) - return false; - // Since the various doamin names map to the same code type, add the version occurrences - // across all domains to see we have all possible versions covered - int vCntr = 0; - for (String thisDomainName : domainMap.keySet()) - { - vCntr += domainMap.get(thisDomainName).size(); - } - return vCntr == generator.globalVersionSet.size(); - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - String margin = Utils.createSpaces(marginSize); - out.println(margin + "[F] " + name + ": " + versionSet); - - for (Integer thisOrdinal : ordinalMap.keySet()) - { - AmqpVersionSet versionList = ordinalMap.get(thisOrdinal); - out.println(margin + " [O] " + thisOrdinal + " : " + versionList.toString()); - } - - for (String thisDomainName : domainMap.keySet()) - { - AmqpVersionSet versionList = domainMap.get(thisDomainName); - out.println(margin + " [D] " + thisDomainName + " : " + versionList.toString()); - } - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (!versionSet.equals(globalVersionSet)) - return false; - if (!domainMap.isVersionConsistent(globalVersionSet)) - return false; - if (!ordinalMap.isVersionConsistent(globalVersionSet)) - return false; - return true; - } + + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + private final AmqpDomainVersionMap _domainMap = new AmqpDomainVersionMap(); + private final AmqpOrdinalVersionMap _ordinalMap = new AmqpOrdinalVersionMap(); + + private final String _name; + private final Generator _generator; + + private final Map<AmqpVersion, String> _versionToDomainMap = new HashMap<AmqpVersion, String>(); + private final Map<AmqpVersion, Integer> _versionToOrdinalMap = new HashMap<AmqpVersion, Integer>(); + + + public AmqpField(String name, Generator generator) + { + _name = name; + _generator = generator; + + } + + public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + _versionSet.add(version); + String domainType; + // Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields. + try + { + domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN)); + } + catch (AmqpParseException e) + { + domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE)); + } + AmqpVersionSet thisVersionList = _domainMap.get(domainType); + if (thisVersionList == null) // First time, create new entry + { + thisVersionList = new AmqpVersionSet(); + _domainMap.put(domainType, thisVersionList); + } + + _versionToDomainMap.put(version, domainType); + _versionToOrdinalMap.put(version, ordinal); + + thisVersionList.add(version); + thisVersionList = _ordinalMap.get(ordinal); + if (thisVersionList == null) // First time, create new entry + { + thisVersionList = new AmqpVersionSet(); + _ordinalMap.put(ordinal, thisVersionList); + } + thisVersionList.add(version); + NodeList nList = fieldNode.getChildNodes(); + for (int i = 0; i < nList.getLength(); i++) + { + Node child = nList.item(i); + if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) + { + String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); + if (value.compareTo("no-gen") == 0) + { + return false; + } + } + } + return true; + } + + public void removeVersion(AmqpVersion version) + { + _domainMap.removeVersion(version); + _ordinalMap.removeVersion(version); + _versionSet.remove(version); + } + + public boolean isCodeTypeConsistent(LanguageConverter converter) + throws AmqpTypeMappingException + { + if (_domainMap.size() == 1) + { + return true; // By definition + } + ArrayList<String> codeTypeList = new ArrayList<String>(); + for (String thisDomainName : _domainMap.keySet()) + { + AmqpVersionSet versionSet = _domainMap.get(thisDomainName); + String codeType = converter.getGeneratedType(thisDomainName, versionSet.first()); + if (!codeTypeList.contains(codeType)) + { + codeTypeList.add(codeType); + } + } + return codeTypeList.size() == 1; + } + + public boolean isConsistent(Generator generator) + throws AmqpTypeMappingException + { + if (!isCodeTypeConsistent(generator)) + { + return false; + } + if (_ordinalMap.size() != 1) + { + return false; + } + // Since the various doamin names map to the same code type, add the version occurrences + // across all domains to see we have all possible versions covered + int vCntr = 0; + for (String thisDomainName : _domainMap.keySet()) + { + vCntr += _domainMap.get(thisDomainName).size(); + } + return vCntr == generator.getVersionSet().size(); + } + + public boolean isTypeAndNameConsistent(Generator generator) + throws AmqpTypeMappingException + { + if (!isCodeTypeConsistent(generator)) + { + return false; + } + // Since the various doamin names map to the same code type, add the version occurrences + // across all domains to see we have all possible versions covered + int vCntr = 0; + for (String thisDomainName : _domainMap.keySet()) + { + vCntr += _domainMap.get(thisDomainName).size(); + } + return vCntr == getVersionSet().size(); + } + + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + out.println(margin + "[F] " + _name + ": " + _versionSet); + + for (Integer thisOrdinal : _ordinalMap.keySet()) + { + AmqpVersionSet versionList = _ordinalMap.get(thisOrdinal); + out.println(margin + " [O] " + thisOrdinal + " : " + versionList.toString()); + } + + for (String thisDomainName : _domainMap.keySet()) + { + AmqpVersionSet versionList = _domainMap.get(thisDomainName); + out.println(margin + " [D] " + thisDomainName + " : " + versionList.toString()); + } + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (!_versionSet.equals(globalVersionSet)) + { + return false; + } + if (!_domainMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_ordinalMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + return true; + } + + + public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet) + { + if (!_versionSet.equals(globalVersionSet)) + { + return false; + } + if (!_domainMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_ordinalMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + return true; + } + + public String getDomain(AmqpVersion version) + { + return _versionToDomainMap.get(version); + } + + public String getConsistentNativeType() + { + return _generator.getNativeType(_generator.getDomainType(getDomain(_versionSet.first()),_versionSet.first())); + } + + public int getOrdinal(AmqpVersion version) + { + return _versionToOrdinalMap.get(version); + } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public AmqpDomainVersionMap getDomainMap() + { + return _domainMap; + } + + public AmqpOrdinalVersionMap getOrdinalMap() + { + return _ordinalMap; + } + + public String getName() + { + return _name; + } + + public LanguageConverter getGenerator() + { + return _generator; + } + + public Map<AmqpVersion, String> getVersionToDomainMap() + { + return _versionToDomainMap; + } + + public Map<AmqpVersion, Integer> getVersionToOrdinalMap() + { + return _versionToOrdinalMap; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java b/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java index c91ec3d623..0bb5e03a61 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java @@ -20,329 +20,433 @@ */ package org.apache.qpid.gentools; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import java.util.TreeMap; @SuppressWarnings("serial") -public class AmqpFieldMap extends TreeMap<String, AmqpField> implements VersionConsistencyCheck +public class AmqpFieldMap implements VersionConsistencyCheck { - public void removeVersion(AmqpVersion version) - { - String[] fieldNameArray = new String[size()]; - keySet().toArray(fieldNameArray); - for (String fieldName : fieldNameArray) - { - get(fieldName).removeVersion(version); - remove(fieldName); - } - } - - public AmqpFieldMap getFieldMapForOrdinal(int ordinal) - { - AmqpFieldMap newMap = new AmqpFieldMap(); - for (String thisFieldName: keySet()) - { - AmqpField field = get(thisFieldName); - TreeMap<Integer, AmqpVersionSet> ordinalMap = field.ordinalMap; - AmqpVersionSet ordinalVersions = ordinalMap.get(ordinal); - if (ordinalVersions != null) - { - newMap.put(field.name, field); - } - } - return newMap; - } - - public AmqpOrdinalFieldMap getMapForVersion(AmqpVersion version, boolean codeTypeFlag, - LanguageConverter converter) - throws AmqpTypeMappingException - { - // TODO: REVIEW THIS! There may be a bug here that affects C++ generation (only with >1 version)... - // If version == null (a common scenario) then the version map is built up on the - // basis of first found item, and ignores other version variations. - // This should probably be disallowed by throwing an NPE, as AmqpOrdinalFieldMap cannot - // represent these possibilities. - // *OR* - // Change the structure of AmqpOrdianlFieldMap to allow for the various combinations that - // will result from version variation - but that is what AmqpFieldMap is... :-$ - AmqpOrdinalFieldMap ordinalFieldMap = new AmqpOrdinalFieldMap(); - for (String thisFieldName: keySet()) - { - AmqpField field = get(thisFieldName); - if (version == null || field.versionSet.contains(version)) - { - // 1. Search for domain name in field domain map with version that matches - String domain = ""; - boolean dFound = false; - for (String thisDomainName : field.domainMap.keySet()) - { - domain = thisDomainName; - AmqpVersionSet versionSet = field.domainMap.get(domain); - if (version == null || versionSet.contains(version)) - { - if (codeTypeFlag) - domain = converter.getGeneratedType(domain, version); - dFound = true; - } - } - - // 2. Search for ordinal in field ordianl map with version that matches - int ordinal = -1; - boolean oFound = false; - for (Integer thisOrdinal : field.ordinalMap.keySet()) - { - ordinal = thisOrdinal; - AmqpVersionSet versionSet = field.ordinalMap.get(ordinal); - if (version == null || versionSet.contains(version)) - oFound = true; - } - - if (dFound && oFound) - { - String[] fieldDomainPair = {field.name, domain}; - ordinalFieldMap.put(ordinal, fieldDomainPair); - } - } - } - return ordinalFieldMap; - } - - public boolean isDomainConsistent(Generator generator, AmqpVersionSet versionSet) - throws AmqpTypeMappingException - { - if (size() != 1) // Only one field for this ordinal - return false; - return get(firstKey()).isConsistent(generator); - } - - public int getNumFields(AmqpVersion version) - { - int fCntr = 0; - for (String thisFieldName : keySet()) - { - AmqpField field = get(thisFieldName); - if (field.versionSet.contains(version)) - fCntr++; - } - return fCntr; - } - - public String parseFieldMap(Method commonGenerateMethod, Method mangledGenerateMethod, - int indentSize, int tabSize, LanguageConverter converter) - throws AmqpTypeMappingException, IllegalAccessException, InvocationTargetException - { - String indent = Utils.createSpaces(indentSize); - String cr = Utils.lineSeparator; - StringBuffer sb = new StringBuffer(); - - if (commonGenerateMethod == null) - { - // Generate warnings in code if required methods are null. - sb.append(indent + "/*********************************************************" + cr); - sb.append(indent + " * WARNING: Generated code could be missing." + cr); - sb.append(indent + " * In call to parseFieldMap(), generation method was null." + cr); - sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); - sb.append(indent + " *********************************************************/" + cr); - } - - Iterator<String> itr = keySet().iterator(); - while (itr.hasNext()) - { - String fieldName = itr.next(); - AmqpField field = get(fieldName); - if (field.isCodeTypeConsistent(converter)) - { - // All versions identical - Common declaration - String domainName = field.domainMap.firstKey(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = converter.getGeneratedType(domainName, versionSet.first()); - if (commonGenerateMethod != null) - sb.append(commonGenerateMethod.invoke(converter, codeType, field, versionSet, - indentSize, tabSize, itr.hasNext())); - } - else if (mangledGenerateMethod != null) // Version-mangled - { - sb.append(mangledGenerateMethod.invoke(converter, field, indentSize, tabSize, - itr.hasNext())); - } - } - return sb.toString(); - } - - public String parseFieldMapOrdinally(Method generateMethod, Method bitGenerateMethod, - int indentSize, int tabSize, Generator codeGenerator) - throws AmqpTypeMappingException, IllegalAccessException, InvocationTargetException - { - String indent = Utils.createSpaces(indentSize); - String cr = Utils.lineSeparator; - StringBuffer sb = new StringBuffer(); - - // Generate warnings in code if required methods are null. - if (generateMethod == null || bitGenerateMethod == null) - { - sb.append(indent + "/***********************************************" + cr); - sb.append(indent + " * WARNING: In call to parseFieldMapOrdinally():" + cr); - if (generateMethod == null) - sb.append(indent + " * => generateMethod is null." + cr); - if (bitGenerateMethod == null) - sb.append(indent + " * => bitGenerateMethod is null." + cr); - sb.append(indent + " * Generated code could be missing." + cr); - sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); - sb.append(indent + " ***********************************************/" + cr); - } - - /* We must process elements in ordinal order because adjacent booleans (bits) - * must be combined into a single byte (in groups of up to 8). Start with shared - * declarations until an ordinal divergence is found. (For most methods where - * there is no difference between versions, this will simplify the generated - * code. */ - - ArrayList<String> bitFieldList = new ArrayList<String>(); - boolean ordinalDivergenceFlag = false; - int ordinal = 0; - while (ordinal < size() && !ordinalDivergenceFlag) - { - /* Since the getFieldMapOrdinal() function may map more than one Field to - * an ordinal, the number of ordinals may be less than the total number of - * fields in the fieldMap. Check for empty fieldmaps... */ - AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(ordinal); - if (ordinalFieldMap.size() > 0) - { - if (ordinalFieldMap.isDomainConsistent(codeGenerator, codeGenerator.globalVersionSet)) - { - String fieldName = ordinalFieldMap.firstKey(); - String domain = ordinalFieldMap.get(fieldName).domainMap.firstKey(); - String domainType = codeGenerator.getDomainType(domain, - codeGenerator.globalVersionSet.first()); - if (domainType.compareTo("bit") == 0) - bitFieldList.add(fieldName); - else if (bitFieldList.size() > 0) - { - // End of bit types - handle deferred bit type generation - if (bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, bitFieldList, ordinal, - indentSize, tabSize)); - bitFieldList.clear(); - } - if (!ordinalDivergenceFlag) - { - // Defer generation of bit types until all adjacent bits have been - // accounted for. - if (bitFieldList.size() == 0 && generateMethod != null) - sb.append(generateMethod.invoke(codeGenerator, domainType, fieldName, ordinal, - indentSize, tabSize)); - } - ordinal++; - } - else - { - ordinalDivergenceFlag = true; - } - } - } - - // Check if there is still more to do under a version-specific breakout - if (ordinalDivergenceFlag && ordinal< size()) - { - // 1. Cycle through all versions in order, create outer if(version) structure - AmqpVersion[] versionArray = new AmqpVersion[codeGenerator.globalVersionSet.size()]; - codeGenerator.globalVersionSet.toArray(versionArray); - for (int v=0; v<versionArray.length; v++) - { - sb.append(indent); - if (v > 0) - sb.append("else "); - sb.append("if (major == " + versionArray[v].getMajor() + " && minor == " + - versionArray[v].getMinor() + ")" + cr); - sb.append(indent + "{" + cr); - - // 2. Cycle though each ordinal from where we left off in the loop above. - ArrayList<String> bitFieldList2 = new ArrayList<String>(bitFieldList); - for (int o = ordinal; o<size(); o++) - { - AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(o); - if (ordinalFieldMap.size() > 0) - { - // 3. Cycle through each of the fields that have this ordinal. - Iterator<String> i = ordinalFieldMap.keySet().iterator(); - while (i.hasNext()) - { - String fieldName = i.next(); - AmqpField field = ordinalFieldMap.get(fieldName); - - // 4. Some fields may have more than one ordinal - match by both - // ordinal and version. - Iterator<Integer> j = field.ordinalMap.keySet().iterator(); - while (j.hasNext()) - { - int thisOrdinal = j.next(); - AmqpVersionSet v1 = field.ordinalMap.get(thisOrdinal); - if (thisOrdinal == o && v1.contains(versionArray[v])) - { - // 5. Now get the domain for this version - int domainCntr = 0; - Iterator<String> k = field.domainMap.keySet().iterator(); - while (k.hasNext()) - { - // Mangle domain-divergent field names - String mangledFieldName = fieldName; - if (field.domainMap.size() > 1) - mangledFieldName += "_" + (domainCntr++); - String domainName = k.next(); - AmqpVersionSet v2 = field.domainMap.get(domainName); - if (v2.contains(versionArray[v])) - { - // 6. (Finally!!) write the declaration - String domainType = codeGenerator.getDomainType(domainName, - versionArray[v]); - if (domainType.compareTo("bit") == 0) - bitFieldList2.add(mangledFieldName); - else if (bitFieldList2.size() > 0) - { - // End of bit types - handle deferred bit type generation - if (bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, - bitFieldList2, o, indentSize + tabSize, - tabSize)); - bitFieldList2.clear(); - } - // Defer generation of bit types until all adjacent bits have - // been accounted for. - if (bitFieldList2.size() == 0 && generateMethod != null) - sb.append(generateMethod.invoke(codeGenerator, domainType, - mangledFieldName, o, indentSize + tabSize, tabSize)); - } - } - } - } - } - } - } - // Check for remaining deferred bits - if (bitFieldList2.size() > 0 && bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, bitFieldList2, size(), - indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - } - } - // Check for remaining deferred bits - else if (bitFieldList.size() > 0 && bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, bitFieldList, size(), - indentSize, tabSize)); - return sb.toString(); - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - for (String thisFieldName : keySet()) - { - AmqpField field = get(thisFieldName); - if (!field.isVersionConsistent(globalVersionSet)) - return false; - } - return true; - } + + private final TreeMap<String, AmqpField> _map = new TreeMap<String, AmqpField>(); + + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + + public void removeVersion(AmqpVersion version) + { + String[] fieldNameArray = new String[size()]; + _map.keySet().toArray(fieldNameArray); + Iterator<Entry<String, AmqpField>> iter = _map.entrySet().iterator(); + + while (iter.hasNext()) + { + Entry<String, AmqpField> entry = iter.next(); + entry.getValue().removeVersion(version); + iter.remove(); + } + } + + public int size() + { + return _map.size(); + + } + + public AmqpFieldMap getFieldMapForOrdinal(int ordinal) + { + AmqpFieldMap newMap = new AmqpFieldMap(); + for (AmqpField field : _map.values()) + { + + TreeMap<Integer, AmqpVersionSet> ordinalMap = field.getOrdinalMap(); + AmqpVersionSet ordinalVersions = ordinalMap.get(ordinal); + if (ordinalVersions != null) + { + newMap.add(field.getName(), field); + } + } + return newMap; + } + + public void add(String name, AmqpField field) + { + _versionSet.addAll(field.getVersionSet()); + _map.put(name, field); + } + + public AmqpOrdinalFieldMap getMapForVersion(AmqpVersion version, boolean codeTypeFlag, + LanguageConverter converter) + { + // TODO: REVIEW THIS! There may be a bug here that affects C++ generation (only with >1 version)... + // If version == null (a common scenario) then the version map is built up on the + // basis of first found item, and ignores other version variations. + // This should probably be disallowed by throwing an NPE, as AmqpOrdinalFieldMap cannot + // represent these possibilities. + // *OR* + // Change the structure of AmqpOrdianlFieldMap to allow for the various combinations that + // will result from version variation - but that is what AmqpFieldMap is... :-$ + AmqpOrdinalFieldMap ordinalFieldMap = new AmqpOrdinalFieldMap(); + for (AmqpField field : _map.values()) + { + + if (version == null || field.getVersionSet().contains(version)) + { + // 1. Search for domain name in field domain map with version that matches + String domain = ""; + boolean dFound = false; + for (String thisDomainName : field.getDomainMap().keySet()) + { + domain = thisDomainName; + AmqpVersionSet versionSet = field.getDomainMap().get(domain); + if (version == null || versionSet.contains(version)) + { + if (codeTypeFlag) + { + domain = converter.getGeneratedType(domain, version); + } + dFound = true; + } + } + + // 2. Search for ordinal in field ordianl map with version that matches + int ordinal = -1; + boolean oFound = false; + for (Integer thisOrdinal : field.getOrdinalMap().keySet()) + { + ordinal = thisOrdinal; + AmqpVersionSet versionSet = field.getOrdinalMap().get(ordinal); + if (version == null || versionSet.contains(version)) + { + oFound = true; + } + } + + if (dFound && oFound) + { + String[] fieldDomainPair = {field.getName(), domain}; + ordinalFieldMap.put(ordinal, fieldDomainPair); + } + } + } + return ordinalFieldMap; + } + + public boolean isDomainConsistent(Generator generator, AmqpVersionSet versionSet) + throws AmqpTypeMappingException + { + if (size() != 1) // Only one field for this ordinal + { + return false; + } + return _map.get(_map.firstKey()).isConsistent(generator); + } + + public int getNumFields(AmqpVersion version) + { + int fCntr = 0; + for (AmqpField field : _map.values()) + { + + if (field.getVersionSet().contains(version)) + { + fCntr++; + } + } + return fCntr; + } + + public String parseFieldMap(CommandGenerateMethod commonGenerateMethod, MangledGenerateMethod mangledGenerateMethod, + int indentSize, int tabSize, LanguageConverter converter) + { + String indent = Utils.createSpaces(indentSize); + String cr = Utils.LINE_SEPARATOR; + StringBuffer sb = new StringBuffer(); + + if (commonGenerateMethod == null) + { + // Generate warnings in code if required methods are null. + sb.append(indent + "/*********************************************************" + cr); + sb.append(indent + " * WARNING: Generated code could be missing." + cr); + sb.append(indent + " * In call to parseFieldMap(), generation method was null." + cr); + sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); + sb.append(indent + " *********************************************************/" + cr); + } + + Iterator<Entry<String, AmqpField>> itr = _map.entrySet().iterator(); + while (itr.hasNext()) + { + Entry<String, AmqpField> entry = itr.next(); + String fieldName = entry.getKey(); + AmqpField field = entry.getValue(); + if (field.isCodeTypeConsistent(converter)) + { + // All versions identical - Common declaration + String domainName = field.getDomainMap().firstKey(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = converter.getGeneratedType(domainName, versionSet.first()); + if (commonGenerateMethod != null) + { + sb.append(commonGenerateMethod.generate(codeType, field, versionSet, + indentSize, tabSize, itr.hasNext())); + } + } + else if (mangledGenerateMethod != null) // Version-mangled + { + sb.append(mangledGenerateMethod.generate(field, indentSize, tabSize, + itr.hasNext())); + } + } + return sb.toString(); + } + + public String parseFieldMapOrdinally(GenerateMethod generateMethod, BitFieldGenerateMethod bitGenerateMethod, + int indentSize, int tabSize, Generator codeGenerator) + { + String indent = Utils.createSpaces(indentSize); + String cr = Utils.LINE_SEPARATOR; + StringBuffer sb = new StringBuffer(); + + // Generate warnings in code if required methods are null. + if (generateMethod == null || bitGenerateMethod == null) + { + sb.append(indent + "/***********************************************" + cr); + sb.append(indent + " * WARNING: In call to parseFieldMapOrdinally():" + cr); + if (generateMethod == null) + { + sb.append(indent + " * => generateMethod is null." + cr); + } + if (bitGenerateMethod == null) + { + sb.append(indent + " * => bitGenerateMethod is null." + cr); + } + sb.append(indent + " * Generated code could be missing." + cr); + sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); + sb.append(indent + " ***********************************************/" + cr); + } + + /* We must process elements in ordinal order because adjacent booleans (bits) + * must be combined into a single byte (in groups of up to 8). Start with shared + * declarations until an ordinal divergence is found. (For most methods where + * there is no difference between versions, this will simplify the generated + * code. */ + + ArrayList<String> bitFieldList = new ArrayList<String>(); + boolean ordinalDivergenceFlag = false; + int ordinal = 0; + while (ordinal < size() && !ordinalDivergenceFlag) + { + /* Since the getFieldMapOrdinal() function may map more than one Field to + * an ordinal, the number of ordinals may be less than the total number of + * fields in the fieldMap. Check for empty fieldmaps... */ + AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(ordinal); + if (ordinalFieldMap.size() > 0) + { + if (ordinalFieldMap.isDomainConsistent(codeGenerator, getVersionSet())) + { + String fieldName = ordinalFieldMap.getFirstFieldName(); + String domain = ordinalFieldMap._map.get(fieldName).getDomainMap().firstKey(); + + String domainType = codeGenerator.getDomainType(domain, + codeGenerator.getVersionSet().first()); + + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldName); + } + else if (bitFieldList.size() > 0) + { + // End of bit types - handle deferred bit type generation + if (bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate(bitFieldList, ordinal, + indentSize, tabSize)); + } + bitFieldList.clear(); + } + if (!ordinalDivergenceFlag) + { + // Defer generation of bit types until all adjacent bits have been + // accounted for. + if (bitFieldList.size() == 0 && generateMethod != null) + { + sb.append(generateMethod.generate(domainType, fieldName, ordinal, + indentSize, tabSize)); + } + } + ordinal++; + } + else + { + ordinalDivergenceFlag = true; + } + } + } + + // Check if there is still more to do under a version-specific breakout + if (ordinalDivergenceFlag && ordinal < size()) + { + // 1. Cycle through all versions in order, create outer if(version) structure + AmqpVersion[] versionArray = new AmqpVersion[getVersionSet().size()]; + getVersionSet().toArray(versionArray); + for (int v = 0; v < versionArray.length; v++) + { + sb.append(indent); + if (v > 0) + { + sb.append("else "); + } + sb.append("if (major == " + versionArray[v].getMajor() + " && minor == " + + versionArray[v].getMinor() + ")" + cr); + sb.append(indent + "{" + cr); + + // 2. Cycle though each ordinal from where we left off in the loop above. + ArrayList<String> bitFieldList2 = new ArrayList<String>(bitFieldList); + for (int o = ordinal; o < size(); o++) + { + AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(o); + if (ordinalFieldMap.size() > 0) + { + // 3. Cycle through each of the fields that have this ordinal. + Iterator<Map.Entry<String, AmqpField>> i = ordinalFieldMap._map.entrySet().iterator(); + while (i.hasNext()) + { + + Map.Entry<String, AmqpField> entry = i.next(); + AmqpField field = entry.getValue(); + String fieldName = entry.getKey(); + + // 4. Some fields may have more than one ordinal - match by both + // ordinal and version. + Iterator<Integer> j = field.getOrdinalMap().keySet().iterator(); + while (j.hasNext()) + { + int thisOrdinal = j.next(); + AmqpVersionSet v1 = field.getOrdinalMap().get(thisOrdinal); + if (thisOrdinal == o && v1.contains(versionArray[v])) + { + // 5. Now get the domain for this version + int domainCntr = 0; + Iterator<String> k = field.getDomainMap().keySet().iterator(); + while (k.hasNext()) + { + // Mangle domain-divergent field names + String mangledFieldName = fieldName; + if (field.getDomainMap().size() > 1) + { + mangledFieldName += "_" + (domainCntr++); + } + String domainName = k.next(); + AmqpVersionSet v2 = field.getDomainMap().get(domainName); + if (v2.contains(versionArray[v])) + { + // 6. (Finally!!) write the declaration + String domainType = codeGenerator.getDomainType(domainName, + versionArray[v]); + if (domainType.compareTo("bit") == 0) + { + bitFieldList2.add(mangledFieldName); + } + else if (bitFieldList2.size() > 0) + { + // End of bit types - handle deferred bit type generation + if (bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate( + bitFieldList2, o, indentSize + tabSize, + tabSize)); + } + bitFieldList2.clear(); + } + // Defer generation of bit types until all adjacent bits have + // been accounted for. + if (bitFieldList2.size() == 0 && generateMethod != null) + { + sb.append(generateMethod.generate(domainType, + mangledFieldName, o, indentSize + tabSize, tabSize)); + } + } + } + } + } + } + } + } + // Check for remaining deferred bits + if (bitFieldList2.size() > 0 && bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate(bitFieldList2, size(), + indentSize + tabSize, tabSize)); + } + sb.append(indent + "}" + cr); + } + } + // Check for remaining deferred bits + else if (bitFieldList.size() > 0 && bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate(bitFieldList, size(), + indentSize, tabSize)); + } + return sb.toString(); + } + + private String getFirstFieldName() + { + return _map.firstKey(); + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + for (String thisFieldName : _map.keySet()) + { + AmqpField field = _map.get(thisFieldName); + if (!field.isVersionConsistent(globalVersionSet)) + { + return false; + } + } + return true; + } + + public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet) + { + for (String thisFieldName : _map.keySet()) + { + AmqpField field = _map.get(thisFieldName); + if (!field.isVersionInterfaceConsistent(globalVersionSet)) + { + return false; + } + } + return true; + } + + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public Collection<AmqpField> values() + { + return _map.values(); + } + + public AmqpField get(String fieldName) + { + return _map.get(fieldName); + } + + public void remove(String fieldName) + { + _map.remove(fieldName); + } + + public Set<String> keySet() + { + return _map.keySet(); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java b/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java index 048221bda8..5993a1b715 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java @@ -26,46 +26,52 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpFlagMap extends TreeMap<Boolean, AmqpVersionSet> implements VersionConsistencyCheck { - public boolean isSet() - { - return containsKey(true); - } - - public String toString() - { - AmqpVersionSet versionSet = get(true); - if (versionSet != null) - return versionSet.toString(); - return ""; - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (size() != 1) - return false; - return get(firstKey()).equals(globalVersionSet); - } - - public boolean removeVersion(AmqpVersion version) - { - Boolean res = false; - ArrayList<Boolean> removeList = new ArrayList<Boolean>(); - for (Boolean flag : keySet()) - { - AmqpVersionSet versionSet = get(flag); - if (versionSet.contains(version)) - { - versionSet.remove(version); - if (versionSet.isEmpty()) - removeList.add(flag); - res = true; - } - } - // Get rid of flags no longer in use - for (Boolean flag : removeList) - { - remove(flag); - } - return res; - } + public boolean isSet() + { + return containsKey(true); + } + + public String toString() + { + AmqpVersionSet versionSet = get(true); + if (versionSet != null) + { + return versionSet.toString(); + } + return ""; + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + { + return false; + } + return get(firstKey()).equals(globalVersionSet); + } + + public boolean removeVersion(AmqpVersion version) + { + Boolean res = false; + ArrayList<Boolean> removeList = new ArrayList<Boolean>(); + for (Boolean flag : keySet()) + { + AmqpVersionSet versionSet = get(flag); + if (versionSet.contains(version)) + { + versionSet.remove(version); + if (versionSet.isEmpty()) + { + removeList.add(flag); + } + res = true; + } + } + // Get rid of flags no longer in use + for (Boolean flag : removeList) + { + remove(flag); + } + return res; + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpMethod.java b/gentools/src/org/apache/qpid/gentools/AmqpMethod.java index ce963465de..4ec39b209e 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpMethod.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpMethod.java @@ -20,183 +20,332 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + public class AmqpMethod implements Printable, NodeAware, VersionConsistencyCheck { - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpFieldMap fieldMap; - public String name; - public AmqpOrdinalVersionMap indexMap; - public AmqpFlagMap clientMethodFlagMap; // Method called on client (<chassis name="server"> in XML) - public AmqpFlagMap serverMethodFlagMap; // Method called on server (<chassis name="client"> in XML) - - public AmqpMethod(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - fieldMap = new AmqpFieldMap(); - indexMap = new AmqpOrdinalVersionMap(); - clientMethodFlagMap = new AmqpFlagMap(); - serverMethodFlagMap = new AmqpFlagMap(); - } - - public boolean addFromNode(Node methodNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - boolean serverChassisFlag = false; - boolean clientChassisFlag = false; - int index = Utils.getNamedIntegerAttribute(methodNode, "index"); - AmqpVersionSet indexVersionSet = indexMap.get(index); - if (indexVersionSet != null) - indexVersionSet.add(version); - else - { - indexVersionSet = new AmqpVersionSet(); - indexVersionSet.add(version); - indexMap.put(index, indexVersionSet); - } - NodeList nList = methodNode.getChildNodes(); - int fieldCntr = fieldMap.size(); - for (int i=0; i<nList.getLength(); i++) - { - Node child = nList.item(i); - if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) - { - String fieldName = converter.prepareDomainName(Utils.getNamedAttribute(child, - Utils.ATTRIBUTE_NAME)); - AmqpField thisField = fieldMap.get(fieldName); - if (thisField == null) - { - thisField = new AmqpField(fieldName, converter); - fieldMap.put(fieldName, thisField); - } - if (!thisField.addFromNode(child, fieldCntr++, version)) - { - String className = converter.prepareClassName(Utils.getNamedAttribute(methodNode.getParentNode(), - Utils.ATTRIBUTE_NAME)); - String methodName = converter.prepareMethodName(Utils.getNamedAttribute(methodNode, - Utils.ATTRIBUTE_NAME)); - System.out.println("INFO: Generation supression tag found for field " + - className + "." + methodName + "." + fieldName + " - removing."); - thisField.removeVersion(version); - fieldMap.remove(fieldName); - } - } - else if (child.getNodeName().compareTo(Utils.ELEMENT_CHASSIS) == 0) - { - String chassisName = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_NAME); - if (chassisName.compareTo("server") == 0) - serverChassisFlag = true; - else if (chassisName.compareTo("client") == 0) - clientChassisFlag = true; - } - else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) - { - String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); - if (value.compareTo("no-gen") == 0) - return false; - } - } - processChassisFlags(serverChassisFlag, clientChassisFlag, version); - return true; - } - - public void removeVersion(AmqpVersion version) - { - clientMethodFlagMap.removeVersion(version); - serverMethodFlagMap.removeVersion(version); - indexMap.removeVersion(version); - fieldMap.removeVersion(version); - versionSet.remove(version); - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - String margin = Utils.createSpaces(marginSize); - String tab = Utils.createSpaces(tabSize); - out.println(margin + "[M] " + name + " {" + (serverMethodFlagMap.isSet() ? "S " + - serverMethodFlagMap + (clientMethodFlagMap.isSet() ? ", " : "") : "") + - (clientMethodFlagMap.isSet() ? "C " + clientMethodFlagMap : "") + "}" + ": " + - versionSet); - - for (Integer thisIndex : indexMap.keySet()) - { - AmqpVersionSet indexVersionSet = indexMap.get(thisIndex); - out.println(margin + tab + "[I] " + thisIndex + indexVersionSet); - } - - for (String thisFieldName : fieldMap.keySet()) - { - AmqpField thisField = fieldMap.get(thisFieldName); - thisField.print(out, marginSize + tabSize, tabSize); - } - } - - protected void processChassisFlags(boolean serverFlag, boolean clientFlag, AmqpVersion version) - { - AmqpVersionSet versionSet = serverMethodFlagMap.get(serverFlag); - if (versionSet != null) - versionSet.add(version); - else - { - versionSet = new AmqpVersionSet(); - versionSet.add(version); - serverMethodFlagMap.put(serverFlag, versionSet); - } - - versionSet = clientMethodFlagMap.get(clientFlag); - if (versionSet != null) - versionSet.add(version); - else - { - versionSet = new AmqpVersionSet(); - versionSet.add(version); - clientMethodFlagMap.put(clientFlag, versionSet); - } - } - - public AmqpOverloadedParameterMap getOverloadedParameterLists(AmqpVersionSet globalVersionSet, - Generator generator) - throws AmqpTypeMappingException - { - AmqpOverloadedParameterMap parameterVersionMap = new AmqpOverloadedParameterMap(); - for (AmqpVersion thisVersion : globalVersionSet) - { - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(thisVersion, true, generator); - AmqpVersionSet methodVersionSet = parameterVersionMap.get(ordinalFieldMap); - if (methodVersionSet == null) - { - methodVersionSet = new AmqpVersionSet(); - methodVersionSet.add(thisVersion); - parameterVersionMap.put(ordinalFieldMap, methodVersionSet); - } - else - { - methodVersionSet.add(thisVersion); - } - } - return parameterVersionMap; - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (!versionSet.equals(globalVersionSet)) - return false; - if (!clientMethodFlagMap.isVersionConsistent(globalVersionSet)) - return false; - if (!serverMethodFlagMap.isVersionConsistent(globalVersionSet)) - return false; - if (!indexMap.isVersionConsistent(globalVersionSet)) - return false; - if (!fieldMap.isVersionConsistent(globalVersionSet)) - return false; - return true; - } + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + private final AmqpFieldMap _fieldMap = new AmqpFieldMap(); + + private final AmqpOrdinalVersionMap _indexMap = new AmqpOrdinalVersionMap(); + private final AmqpFlagMap _clientMethodFlagMap = new AmqpFlagMap(); // Method called on client (<chassis name="server"> in XML) + private final AmqpFlagMap _serverMethodFlagMap = new AmqpFlagMap(); // Method called on server (<chassis name="client"> in XML) + + private final Map<AmqpVersion, AmqpFieldMap> _versionToFieldsMap = new HashMap<AmqpVersion, AmqpFieldMap>(); + + private final Map<AmqpVersion, AtomicInteger> _versionToFieldCount = new HashMap<AmqpVersion, AtomicInteger>(); + + private final String _name; + private final Generator _generator; + + + public AmqpMethod(String name, Generator generator) + { + _name = name; + _generator = generator; + } + + public boolean addFromNode(Node methodNode, int ordinal, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + _versionSet.add(version); + boolean serverChassisFlag = false; + boolean clientChassisFlag = false; + int index = Utils.getNamedIntegerAttribute(methodNode, "index"); + AmqpVersionSet indexVersionSet = _indexMap.get(index); + if (indexVersionSet != null) + { + indexVersionSet.add(version); + } + else + { + indexVersionSet = new AmqpVersionSet(); + indexVersionSet.add(version); + _indexMap.put(index, indexVersionSet); + } + NodeList nList = methodNode.getChildNodes(); + AtomicInteger fieldCntr = _versionToFieldCount.get(version); + if(fieldCntr == null) + { + fieldCntr = new AtomicInteger(0); + _versionToFieldCount.put(version, fieldCntr); + } + for (int i = 0; i < nList.getLength(); i++) + { + Node child = nList.item(i); + if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) + { + String fieldName = _generator.prepareDomainName(Utils.getNamedAttribute(child, + Utils.ATTRIBUTE_NAME)); + AmqpField thisField = _fieldMap.get(fieldName); + AmqpFieldMap versionSpecificFieldMap = _versionToFieldsMap.get(version); + if (versionSpecificFieldMap == null) + { + versionSpecificFieldMap = new AmqpFieldMap(); + _versionToFieldsMap.put(version, versionSpecificFieldMap); + } + + + if (thisField == null) + { + thisField = new AmqpField(fieldName, _generator); + _fieldMap.add(fieldName, thisField); + } + + AmqpField versionSpecificField = new AmqpField(fieldName, _generator); + versionSpecificFieldMap.add(fieldName, versionSpecificField); + + versionSpecificField.addFromNode(child, fieldCntr.intValue(), version); + + if (!thisField.addFromNode(child, fieldCntr.getAndIncrement(), version)) + { + String className = _generator.prepareClassName(Utils.getNamedAttribute(methodNode.getParentNode(), + Utils.ATTRIBUTE_NAME)); + String methodName = _generator.prepareMethodName(Utils.getNamedAttribute(methodNode, + Utils.ATTRIBUTE_NAME)); + System.out.println("INFO: Generation supression tag found for field " + + className + "." + methodName + "." + fieldName + " - removing."); + thisField.removeVersion(version); + _fieldMap.remove(fieldName); + } + } + else if (child.getNodeName().compareTo(Utils.ELEMENT_CHASSIS) == 0) + { + String chassisName = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_NAME); + if (chassisName.compareTo("server") == 0) + { + serverChassisFlag = true; + } + else if (chassisName.compareTo("client") == 0) + { + clientChassisFlag = true; + } + } + else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) + { + String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); + if (value.compareTo("no-gen") == 0) + { + return false; + } + } + } + processChassisFlags(serverChassisFlag, clientChassisFlag, version); + return true; + } + + public void removeVersion(AmqpVersion version) + { + _clientMethodFlagMap.removeVersion(version); + _serverMethodFlagMap.removeVersion(version); + _indexMap.removeVersion(version); + _fieldMap.removeVersion(version); + _versionSet.remove(version); + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + String tab = Utils.createSpaces(tabSize); + out.println(margin + "[M] " + _name + " {" + (_serverMethodFlagMap.isSet() ? "S " + + _serverMethodFlagMap + ( + _clientMethodFlagMap.isSet() ? ", " : "") : "") + + (_clientMethodFlagMap.isSet() + ? "C " + _clientMethodFlagMap : "") + "}" + ": " + + _versionSet); + + for (Integer thisIndex : _indexMap.keySet()) + { + AmqpVersionSet indexVersionSet = _indexMap.get(thisIndex); + out.println(margin + tab + "[I] " + thisIndex + indexVersionSet); + } + + for (String thisFieldName : _fieldMap.keySet()) + { + AmqpField thisField = _fieldMap.get(thisFieldName); + thisField.print(out, marginSize + tabSize, tabSize); + } + } + + protected void processChassisFlags(boolean serverFlag, boolean clientFlag, AmqpVersion version) + { + AmqpVersionSet versionSet = _serverMethodFlagMap.get(serverFlag); + if (versionSet != null) + { + versionSet.add(version); + } + else + { + versionSet = new AmqpVersionSet(); + versionSet.add(version); + _serverMethodFlagMap.put(serverFlag, versionSet); + } + + versionSet = _clientMethodFlagMap.get(clientFlag); + if (versionSet != null) + { + versionSet.add(version); + } + else + { + versionSet = new AmqpVersionSet(); + versionSet.add(version); + _clientMethodFlagMap.put(clientFlag, versionSet); + } + } + + public AmqpOverloadedParameterMap getOverloadedParameterLists(AmqpVersionSet globalVersionSet, + Generator generator) + throws AmqpTypeMappingException + { + AmqpOverloadedParameterMap parameterVersionMap = new AmqpOverloadedParameterMap(); + for (AmqpVersion thisVersion : globalVersionSet) + { + AmqpOrdinalFieldMap ordinalFieldMap = _fieldMap.getMapForVersion(thisVersion, true, generator); + AmqpVersionSet methodVersionSet = parameterVersionMap.get(ordinalFieldMap); + if (methodVersionSet == null) + { + methodVersionSet = new AmqpVersionSet(); + methodVersionSet.add(thisVersion); + parameterVersionMap.put(ordinalFieldMap, methodVersionSet); + } + else + { + methodVersionSet.add(thisVersion); + } + } + return parameterVersionMap; + } + + public boolean isVersionInterfaceConsistent() + { + return isVersionInterfaceConsistent(_generator.getVersionSet()); + } + + public boolean isVersionInterfaceConsistent(AmqpVersionSet globalVersionSet) + { + if (!_versionSet.equals(globalVersionSet)) + { + return false; + } + if (!_clientMethodFlagMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_serverMethodFlagMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_fieldMap.isVersionInterfaceConsistent(globalVersionSet)) + { + return false; + } + return true; + } + + public boolean isVersionConsistent() + { + return isVersionConsistent(_generator.getVersionSet()); + } + + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + return isVersionInterfaceConsistent(globalVersionSet) + && _indexMap.isVersionConsistent(globalVersionSet) + && _fieldMap.isVersionConsistent(globalVersionSet); + } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public AmqpFieldMap getFieldMap() + { + return _fieldMap; + } + + public AmqpOrdinalVersionMap getIndexMap() + { + return _indexMap; + } + + public AmqpFlagMap getClientMethodFlagMap() + { + return _clientMethodFlagMap; + } + + public AmqpFlagMap getServerMethodFlagMap() + { + return _serverMethodFlagMap; + } + + public Map<AmqpVersion, AmqpFieldMap> getVersionToFieldsMap() + { + return _versionToFieldsMap; + } + + public String getName() + { + return _name; + } + + public LanguageConverter getGenerator() + { + return _generator; + } + + public SingleVersionMethod asSingleVersionMethod(AmqpVersion version) + { + return new SingleVersionMethod(this, version, _generator); + } + + public Collection<AmqpField> getFields() + { + return _fieldMap.values(); + } + + public boolean isCommon(AmqpField field) + { + return field.getVersionSet().equals(getVersionSet()) && field.isTypeAndNameConsistent(_generator); + } + + public boolean isConsistentServerMethod() + { + AmqpVersionSet serverVersions = _serverMethodFlagMap.get(true); + return (serverVersions != null) && serverVersions.containsAll(_generator.getVersionSet()); + } + + + public boolean isConsistentClientMethod() + { + AmqpVersionSet clientVersions = _clientMethodFlagMap.get(true); + return (clientVersions != null) && clientVersions.containsAll(_generator.getVersionSet()); + } + + public boolean isServerMethod(AmqpVersion version) + { + AmqpVersionSet serverVersions = _serverMethodFlagMap.get(true); + return (serverVersions != null) && serverVersions.contains(version); + } + + + public boolean isClientMethod(AmqpVersion version) + { + AmqpVersionSet clientVersions = _clientMethodFlagMap.get(true); + return (clientVersions != null) && clientVersions.contains(version); + } + + public boolean inAllVersions() + { + return _versionSet.containsAll(_generator.getVersionSet()); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java b/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java index 59eedd2a2b..d98dab4a39 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java @@ -25,12 +25,12 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpMethodMap extends TreeMap<String, AmqpMethod> { - public void removeVersion(AmqpVersion version) - { - for (String methodName : keySet()) - { - get(methodName).removeVersion(version); - } - } + public void removeVersion(AmqpVersion version) + { + for (String methodName : keySet()) + { + get(methodName).removeVersion(version); + } + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpModel.java b/gentools/src/org/apache/qpid/gentools/AmqpModel.java index 721247a4b2..45f0adb18d 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpModel.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpModel.java @@ -20,61 +20,113 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Collection; + public class AmqpModel implements Printable, NodeAware { - public LanguageConverter converter; - public AmqpClassMap classMap; - - public AmqpModel(LanguageConverter converter) - { - this.converter = converter; - this.converter.setModel(this); - classMap = new AmqpClassMap(); - } - - public boolean addFromNode(Node n, int o, AmqpVersion v) - throws AmqpParseException, AmqpTypeMappingException - { - NodeList nList = n.getChildNodes(); - int eCntr = 0; - for (int i=0; i<nList.getLength(); i++) - { - Node c = nList.item(i); - if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0) - { - String className = converter.prepareClassName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); - AmqpClass thisClass = classMap.get(className); - if (thisClass == null) - { - thisClass = new AmqpClass(className, converter); - classMap.put(className, thisClass); - } - if (!thisClass.addFromNode(c, eCntr++, v)) - { - System.out.println("INFO: Generation supression tag found for class " + className + " - removing."); - thisClass.removeVersion(v); - classMap.remove(className); - } - } - } - return true; - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - out.println(Utils.createSpaces(marginSize) + - "[C]=class; [M]=method; [F]=field; [D]=domain; [I]=index; [O]=ordinal" + Utils.lineSeparator); - out.println(Utils.createSpaces(marginSize) + "Model:"); - - for (String thisClassName : classMap.keySet()) - { - AmqpClass thisClass = classMap.get(thisClassName); - thisClass.print(out, marginSize + tabSize, tabSize); - } - } + private final Generator _generator; + private final AmqpClassMap classMap = new AmqpClassMap(); + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + + private final Map<AmqpVersion, AmqpClassMap> _versionToClassMapMap = new HashMap<AmqpVersion, AmqpClassMap>(); + + public AmqpModel(Generator generator) + { + _generator = generator; + } + + public AmqpClassMap getAmqpClassMap(AmqpVersion version) + { + return _versionToClassMapMap.get(version); + } + + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public boolean addFromNode(Node n, int o, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + _versionSet.add(version); + NodeList nList = n.getChildNodes(); + + AmqpClassMap versionSpecificClassMap = _versionToClassMapMap.get(version); + + if (versionSpecificClassMap == null) + { + versionSpecificClassMap = new AmqpClassMap(); + _versionToClassMapMap.put(version, versionSpecificClassMap); + } + + int eCntr = 0; + for (int i = 0; i < nList.getLength(); i++) + { + Node c = nList.item(i); + if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0) + { + String className = _generator.prepareClassName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); + AmqpClass thisClass = classMap.get(className); + if (thisClass == null) + { + thisClass = new AmqpClass(className, _generator); + classMap.put(className, thisClass); + } + + AmqpClass versionSpecificClass = new AmqpClass(className, _generator); + versionSpecificClassMap.put(className, versionSpecificClass); + + versionSpecificClass.addFromNode(c, eCntr, version); + + if (!thisClass.addFromNode(c, eCntr++, version)) + { + System.out.println("INFO: Generation supression tag found for class " + className + " - removing."); + thisClass.removeVersion(version); + classMap.remove(className); + } + } + } + return true; + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + out.println(Utils.createSpaces(marginSize) + + "[C]=class; [M]=method; [F]=field; [D]=domain; [I]=index; [O]=ordinal" + Utils.LINE_SEPARATOR); + out.println(Utils.createSpaces(marginSize) + "Model:"); + + for (String thisClassName : classMap.keySet()) + { + AmqpClass thisClass = classMap.get(thisClassName); + thisClass.print(out, marginSize + tabSize, tabSize); + } + } + + public LanguageConverter getGenerator() + { + return _generator; + } + + public AmqpClassMap getClassMap() + { + return classMap; + } + + + public Collection<AmqpClass> getClasses() + { + return classMap.values(); + } + + public SingleVersionModel asSingleVersionModel() + { + return new SingleVersionModel(this, getVersionSet().first(), _generator); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java index 34d3b7ca5f..0633eff1e1 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java @@ -27,63 +27,70 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpOrdinalFieldMap extends TreeMap<Integer, String[]> implements Comparable { - protected static final int FIELD_DOMAIN = 1; - protected boolean codeTypeFlag = false; - - 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; - } - - public String toString() - { - StringBuffer sb = new StringBuffer(); - for (Integer thisOrdinal : keySet()) - { - String[] pair = get(thisOrdinal); - sb.append("[" + thisOrdinal + "] " + pair[0] + " : " + pair[1] + Utils.lineSeparator); - } - return sb.toString(); - } + + + 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; + } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + for (Integer thisOrdinal : keySet()) + { + String[] pair = get(thisOrdinal); + sb.append("[" + thisOrdinal + "] " + pair[0] + " : " + pair[1] + Utils.LINE_SEPARATOR); + } + return sb.toString(); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java index 3706c9391d..33a539f9f6 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java @@ -26,47 +26,52 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpOrdinalVersionMap extends TreeMap<Integer, AmqpVersionSet> implements VersionConsistencyCheck { - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (size() != 1) - return false; - return get(firstKey()).equals(globalVersionSet); - } - + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + { + return false; + } + return get(firstKey()).equals(globalVersionSet); + } + public int getOrdinal(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { - for (Integer thisOrdinal : keySet()) + for (Integer thisOrdinal : keySet()) { AmqpVersionSet versionSet = get(thisOrdinal); if (versionSet.contains(version)) + { return thisOrdinal; + } } throw new AmqpTypeMappingException("Unable to locate version " + version + " in ordianl version map."); } - - public boolean removeVersion(AmqpVersion version) - { - Boolean res = false; - ArrayList<Integer> removeList = new ArrayList<Integer>(); - for (Integer ordinal : keySet()) - { - AmqpVersionSet versionSet = get(ordinal); - if (versionSet.contains(version)) - { - versionSet.remove(version); - if (versionSet.isEmpty()) - { - removeList.add(ordinal); - } - res = true; - } - } - // Get rid of ordinals no longer in use - for (Integer ordinal : removeList) - { - remove(ordinal); - } - return res; - } + + public boolean removeVersion(AmqpVersion version) + { + Boolean res = false; + ArrayList<Integer> removeList = new ArrayList<Integer>(); + for (Integer ordinal : keySet()) + { + AmqpVersionSet versionSet = get(ordinal); + if (versionSet.contains(version)) + { + versionSet.remove(version); + if (versionSet.isEmpty()) + { + removeList.add(ordinal); + } + res = true; + } + } + // Get rid of ordinals no longer in use + for (Integer ordinal : removeList) + { + remove(ordinal); + } + return res; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpParseException.java b/gentools/src/org/apache/qpid/gentools/AmqpParseException.java index 4d9f495390..3f3d4611fc 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpParseException.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpParseException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class AmqpParseException extends Exception +public class AmqpParseException extends RuntimeException { - public AmqpParseException(String msg) - { - super(msg); - } + public AmqpParseException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java b/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java index b1e6f3d712..1ac09ea453 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class AmqpTemplateException extends Exception +public class AmqpTemplateException extends RuntimeException { - public AmqpTemplateException(String msg) - { - super(msg); - } + public AmqpTemplateException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java b/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java index 1053543fdd..127a8835b0 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class AmqpTypeMappingException extends Exception +public class AmqpTypeMappingException extends RuntimeException { - public AmqpTypeMappingException(String msg) - { - super(msg); - } + public AmqpTypeMappingException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpVersion.java b/gentools/src/org/apache/qpid/gentools/AmqpVersion.java index 579d8e28b2..dbeef1b895 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpVersion.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpVersion.java @@ -22,47 +22,51 @@ package org.apache.qpid.gentools; public class AmqpVersion implements Comparable<AmqpVersion> { - private int major; - private int minor; - - public AmqpVersion(int major, int minor) - { - this.major = major; - this.minor = minor; - } + private final int _major; + private final int _minor; - public AmqpVersion(AmqpVersion version) - { - this.major = version.major; - this.minor = version.minor; - } - - public int getMajor() - { - return major; - } - - public int getMinor() - { - return minor; - } - - public int compareTo(AmqpVersion v) - { - if (major != v.major) - return major - v.major; - if (minor != v.minor) - return minor - v.minor; - return 0; - } - - public String namespace() - { - return "ver_" + major + "_" + minor; - } - - public String toString() - { - return major + "-" + minor; - } + public AmqpVersion(int major, int minor) + { + _major = major; + _minor = minor; + } + + public AmqpVersion(AmqpVersion version) + { + _major = version.getMajor(); + _minor = version.getMinor(); + } + + public int getMajor() + { + return _major; + } + + public int getMinor() + { + return _minor; + } + + public int compareTo(AmqpVersion v) + { + if (_major != v.getMajor()) + { + return _major - v.getMajor(); + } + if (_minor != v.getMinor()) + { + return _minor - v.getMinor(); + } + return 0; + } + + public String namespace() + { + return "ver_" + _major + "_" + _minor; + } + + public String toString() + { + return _major + "-" + _minor; + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java b/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java index 4406893cbb..6419e23a1e 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java @@ -21,7 +21,6 @@ package org.apache.qpid.gentools; import java.io.PrintStream; -//import java.util.ArrayList; import java.util.Iterator; import java.util.TreeSet; @@ -30,35 +29,39 @@ public class AmqpVersionSet extends TreeSet<AmqpVersion> implements Printable, C { public AmqpVersionSet() { - super(); + super(); } - + public AmqpVersionSet(AmqpVersion version) { - super(); + super(); add(version); } - + public AmqpVersion find(AmqpVersion version) { - for (AmqpVersion v : this) - { - if (v.compareTo(version) == 0) - return v; - } - return null; + for (AmqpVersion v : this) + { + if (v.compareTo(version) == 0) + { + return v; + } + } + return null; + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + out.print(Utils.createSpaces(marginSize) + "Version Set: " + toString() + Utils.LINE_SEPARATOR); } - - public void print(PrintStream out, int marginSize, int tabSize) - { - out.print(Utils.createSpaces(marginSize) + "Version Set: " + toString() + Utils.lineSeparator); - } - + public int compareTo(AmqpVersionSet other) { int res = size() - other.size(); if (res != 0) + { return res; + } Iterator<AmqpVersion> vItr = iterator(); Iterator<AmqpVersion> oItr = other.iterator(); while (vItr.hasNext() && oItr.hasNext()) @@ -67,7 +70,9 @@ public class AmqpVersionSet extends TreeSet<AmqpVersion> implements Printable, C AmqpVersion oVersion = oItr.next(); res = version.compareTo(oVersion); if (res != 0) + { return res; + } } return 0; } diff --git a/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java b/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java new file mode 100644 index 0000000000..3f1fce6291 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java @@ -0,0 +1,29 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+
+import java.util.List;
+
+public interface BitFieldGenerateMethod
+{
+ String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize);
+}
diff --git a/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java b/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java new file mode 100644 index 0000000000..ed0dd2eea4 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java @@ -0,0 +1,26 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+public interface CommandGenerateMethod
+{
+ String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast);
+}
diff --git a/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java b/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java new file mode 100644 index 0000000000..bd696b01b9 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java @@ -0,0 +1,100 @@ +package org.apache.qpid.gentools;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: U146758
+ * Date: 06-Mar-2007
+ * Time: 09:22:21
+ * To change this template use File | Settings | File Templates.
+ */
+public class ConsolidatedField
+{
+ private final String _name;
+ private final String _type;
+ private final List<String> _underlyingFields = new ArrayList<String>();
+ private final Generator _generator;
+ private boolean _isConsolidated;
+
+ public ConsolidatedField(Generator generator, String name, String type)
+ {
+ this(generator,name,type,name,false);
+ }
+
+ public ConsolidatedField(Generator generator, String name, String type, String firstField)
+ {
+ this(generator,name,type,firstField,true);
+ }
+
+ public ConsolidatedField(Generator generator, String name, String type, String firstField, boolean consolidated)
+ {
+
+ _generator = generator;
+ _name = name;
+ _type = type;
+ _isConsolidated = consolidated;
+ _underlyingFields.add(firstField);
+
+ }
+
+
+ public void setConsolidated(boolean consolidated)
+ {
+ _isConsolidated = consolidated;
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getType()
+ {
+ return _type;
+ }
+
+ public String getNativeType()
+ {
+ return _generator.getNativeType(_type);
+ }
+
+ public String getEncodingType()
+ {
+ return _generator.getEncodingType(_type);
+ }
+
+ public void add(String name)
+ {
+ _underlyingFields.add(name);
+ }
+
+ public Collection<String> getUnderlyingFields()
+ {
+ return Collections.unmodifiableCollection(_underlyingFields);
+ }
+
+ public int getPosition(String fieldName)
+ {
+ return _underlyingFields.indexOf(fieldName);
+ }
+
+ public boolean isConsolidated()
+ {
+ return _isConsolidated;
+ }
+
+ public boolean isFixedSize()
+ {
+ return _generator.isFixedSizeType( getType() );
+ }
+
+ public int getSize()
+ {
+ return _generator.getTypeSize( getType() );
+ }
+
+}
diff --git a/gentools/src/org/apache/qpid/gentools/CppGenerator.java b/gentools/src/org/apache/qpid/gentools/CppGenerator.java index 06454ddeb9..4f58cba34e 100644 --- a/gentools/src/org/apache/qpid/gentools/CppGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/CppGenerator.java @@ -21,37 +21,35 @@ package org.apache.qpid.gentools; import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.TreeMap; public class CppGenerator extends Generator { - protected static final String versionNamespaceStartToken = "${version_namespace_start}"; - protected static final String versionNamespaceEndToken = "${version_namespace_end}"; - - // TODO: Move this to parent class - protected static final int FIELD_NAME = 0; - protected static final int FIELD_CODE_TYPE = 1; - + protected static final String versionNamespaceStartToken = "${version_namespace_start}"; + protected static final String versionNamespaceEndToken = "${version_namespace_end}"; + + // TODO: Move this to parent class + protected static final int FIELD_NAME = 0; + protected static final int FIELD_CODE_TYPE = 1; + /** * A complete list of C++ reserved words. The names of varous XML elements within the AMQP * specification file are used for C++ identifier names in the generated code. Each proposed * name is checked against this list and is modified (by adding an '_' to the end of the * name - see function parseForReservedWords()) if found to be present. */ - 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"}; - + 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"}; + /** * Although not reserved words, the following list of variable names that may cause compile * problems within a C++ environment because they clash with common #includes. The names of @@ -61,87 +59,89 @@ public class CppGenerator extends Generator * to be present. This list is best added to on an as-needed basis. */ protected static final String[] cppCommonDefines = {"string"}; - + // TODO: Move this to the Generator superclass? protected boolean quietFlag; // Supress warning messages to the console - - 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 CppGenerator(AmqpVersionSet versionList) - { - super(versionList); + + 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 CppGenerator() + { + super(); quietFlag = true; - // Load C++ 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). - typeMap.put("bit", new DomainInfo( - "bool", // type - "~", // size - "", // encodeExpression - "")); // decodeExpression - typeMap.put("content", new DomainInfo( - "Content", // type - "#.size()", // size - "buffer.putContent(#)", // encodeExpression - "buffer.getContent(#)")); // decodeExpression - typeMap.put("long", new DomainInfo( - "u_int32_t", // type - "4", // size - "buffer.putLong(#)", // encodeExpression - "# = buffer.getLong()")); // decodeExpression - typeMap.put("longlong", new DomainInfo( - "u_int64_t", // type - "8", // size + // Load C++ 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). + typeMap.put("bit", new DomainInfo( + "bool", // type + "~", // size + "", // encodeExpression + "")); // decodeExpression + typeMap.put("content", new DomainInfo( + "Content", // type + "#.size()", // size + "buffer.putContent(#)", // encodeExpression + "buffer.getContent(#)")); // decodeExpression + typeMap.put("long", new DomainInfo( + "u_int32_t", // type + "4", // size + "buffer.putLong(#)", // encodeExpression + "# = buffer.getLong()")); // decodeExpression + typeMap.put("longlong", new DomainInfo( + "u_int64_t", // type + "8", // size "buffer.putLongLong(#)", // encodeExpression - "# = buffer.getLongLong()")); // decodeExpression - typeMap.put("longstr", new DomainInfo( - "string", // type - "4 + #.length()", // size + "# = buffer.getLongLong()")); // decodeExpression + typeMap.put("longstr", new DomainInfo( + "string", // type + "4 + #.length()", // size "buffer.putLongString(#)", // encodeExpression - "buffer.getLongString(#)")); // decodeExpression - typeMap.put("octet", new DomainInfo( - "u_int8_t", // type - "1", // size - "buffer.putOctet(#)", // encodeExpression - "# = buffer.getOctet()")); // decodeExpression - typeMap.put("short", new DomainInfo( - "u_int16_t", // type - "2", // size - "buffer.putShort(#)", // encodeExpression - "# = buffer.getShort()")); // decodeExpression - typeMap.put("shortstr", new DomainInfo( - "string", // type - "1 + #.length()", // size + "buffer.getLongString(#)")); // decodeExpression + typeMap.put("octet", new DomainInfo( + "u_int8_t", // type + "1", // size + "buffer.putOctet(#)", // encodeExpression + "# = buffer.getOctet()")); // decodeExpression + typeMap.put("short", new DomainInfo( + "u_int16_t", // type + "2", // size + "buffer.putShort(#)", // encodeExpression + "# = buffer.getShort()")); // decodeExpression + typeMap.put("shortstr", new DomainInfo( + "string", // type + "1 + #.length()", // size "buffer.putShortString(#)", // encodeExpression - "buffer.getShortString(#)")); // decodeExpression - typeMap.put("table", new DomainInfo( - "FieldTable", // type - "#.size()", // size + "buffer.getShortString(#)")); // decodeExpression + typeMap.put("table", new DomainInfo( + "FieldTable", // type + "#.size()", // size "buffer.putFieldTable(#)", // encodeExpression - "buffer.getFieldTable(#)")); // decodeExpression - typeMap.put("timestamp", new DomainInfo( - "u_int64_t", // type - "8", // size + "buffer.getFieldTable(#)")); // decodeExpression + typeMap.put("timestamp", new DomainInfo( + "u_int64_t", // type + "8", // size "buffer.putLongLong(#)", // encodeExpression - "buffer.getLongLong(#)")); // decodeExpression - } + "buffer.getLongLong(#)")); // decodeExpression + } + public boolean isQuietFlag() { @@ -152,40 +152,33 @@ public class CppGenerator extends Generator { this.quietFlag = quietFlag; } - - // === Start of methods for Interface LanguageConverter === - - public String prepareClassName(String className) - { - return camelCaseName(className, true); - } - - public String prepareMethodName(String methodName) - { - return camelCaseName(methodName, false); - } - - public String prepareDomainName(String domainName) - { - return camelCaseName(domainName, false); - } - - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - if (version == null) - version = globalVersionSet.first(); - return globalDomainMap.getDomainType(domainName, version); - } - - public String getGeneratedType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - String domainType = getDomainType(domainName, version); - if (domainType == null) - { - throw new AmqpTypeMappingException("Domain type \"" + domainName + - "\" not found in C++ typemap."); + + // === Start of methods for Interface LanguageConverter === + + public String prepareClassName(String className) + { + return camelCaseName(className, true); + } + + public String prepareMethodName(String methodName) + { + return camelCaseName(methodName, false); + } + + public String prepareDomainName(String domainName) + { + return camelCaseName(domainName, false); + } + + + public String getGeneratedType(String domainName, AmqpVersion version) + throws AmqpTypeMappingException + { + String domainType = getDomainType(domainName, version); + if (domainType == null) + { + throw new AmqpTypeMappingException("Domain type \"" + domainName + + "\" not found in C++ typemap."); } DomainInfo info = typeMap.get(domainType); if (info == null) @@ -193,228 +186,255 @@ public class CppGenerator extends Generator throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); } return info.type; - } - - // === Abstract methods from class Generator - C++-specific implementation === - - @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 processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[templateStringIndex]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null); - boolean templateProcessedFlag = false; - - // If method is not version consistent, create a namespace for each version - // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken - // once for each namespace. - if (method != null) - { - if (!method.isVersionConsistent(globalVersionSet)) - { - int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken); - int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) + - versionNamespaceEndToken.length(); - if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 && - namespaceStartIndex <= namespaceEndIndex) - { - String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + cr; - sb.delete(namespaceStartIndex, namespaceEndIndex); - for (AmqpVersion v : method.versionSet) - { - StringBuffer nssb = new StringBuffer(namespaceSpan); - processTemplate(nssb, thisClass, method, null, template[templateFileNameIndex], v); - sb.insert(namespaceStartIndex, nssb); - } + } + + // === Abstract methods from class Generator - C++-specific implementation === + + @Override + protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(filenameTemplate); + if (thisClass != null) + { + replaceToken(sb, "${CLASS}", thisClass.getName()); + } + if (method != null) + { + replaceToken(sb, "${METHOD}", method.getName()); + } + if (field != null) + { + replaceToken(sb, "${FIELD}", field.getName()); + } + return sb.toString(); + } + + @Override + protected void processModelTemplate(NamedTemplate template) + { + processTemplate(template, null, null, null, null); + } + + @Override + protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass) + { + processTemplate(template, thisClass, null, null, null); + } + + @Override + protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method) + { + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null, null); + boolean templateProcessedFlag = false; + + // If method is not version consistent, create a namespace for each version + // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken + // once for each namespace. + if (method != null) + { + if (!method.isVersionConsistent(getVersionSet())) + { + int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken); + int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) + + versionNamespaceEndToken.length(); + if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 && + namespaceStartIndex <= namespaceEndIndex) + { + String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + CR; + sb.delete(namespaceStartIndex, namespaceEndIndex); + for (AmqpVersion v : method.getVersionSet()) + { + StringBuffer nssb = new StringBuffer(namespaceSpan); + processTemplate(nssb, thisClass, method, null, template.getName(), v); + sb.insert(namespaceStartIndex, nssb); + } // Process all tokens *not* within the namespace span prior to inserting namespaces - processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); - } - templateProcessedFlag = true; - } - } - // Remove any remaining namespace tags - int nsTokenIndex = sb.indexOf(versionNamespaceStartToken); - while (nsTokenIndex > 0) - { - sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length()); - nsTokenIndex = sb.indexOf(versionNamespaceStartToken); - } - nsTokenIndex = sb.indexOf(versionNamespaceEndToken); - while (nsTokenIndex > 0) - { - sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length()); - nsTokenIndex = sb.indexOf(versionNamespaceEndToken); - } - - if (!templateProcessedFlag) - { - processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); - } - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, AmqpMethod method, - AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[templateStringIndex]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, - AmqpField field, String templateFileName, AmqpVersion version) - throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException - { - try { processAllLists(sb, thisClass, method, version); } - catch (AmqpTemplateException e) - { - System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, version); } - catch (AmqpTemplateException e) - { - System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); - } - } - - @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - if (token.compareTo("${GENERATOR}") == 0) - return generatorInfo; - if (token.compareTo("${CLASS}") == 0 && thisClass != null) - return thisClass.name; - if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) - { - if (version == null) - return String.valueOf(thisClass.indexMap.firstKey()); - return getIndex(thisClass.indexMap, version); - } - if (token.compareTo("${METHOD}") == 0 && method != null) - return method.name; - if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) - { - if (version == null) - return String.valueOf(method.indexMap.firstKey()); - return getIndex(method.indexMap, version); - } - if (token.compareTo("${FIELD}") == 0 && field != null) - return field.name; - if (token.compareTo(versionNamespaceStartToken) == 0 && version != null) - return "namespace " + version.namespace() + cr + "{"; - if (token.compareTo(versionNamespaceEndToken) == 0 && version != null) - return "} // namespace " + version.namespace(); + processTemplate(sb, thisClass, method, null, template.getName(), null); + } + templateProcessedFlag = true; + } + } + // Remove any remaining namespace tags + int nsTokenIndex = sb.indexOf(versionNamespaceStartToken); + while (nsTokenIndex > 0) + { + sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length()); + nsTokenIndex = sb.indexOf(versionNamespaceStartToken); + } + nsTokenIndex = sb.indexOf(versionNamespaceEndToken); + while (nsTokenIndex > 0) + { + sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length()); + nsTokenIndex = sb.indexOf(versionNamespaceEndToken); + } + + if (!templateProcessedFlag) + { + processTemplate(sb, thisClass, method, null, template.getName(), null); + } + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + @Override + protected void processTemplate(NamedTemplate template, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version); + processTemplate(sb, thisClass, method, field, template.getName(), null); + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, + AmqpField field, String templateFileName, AmqpVersion version) + { + try + { + processAllLists(sb, thisClass, method, version); + } + catch (AmqpTemplateException e) + { + System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); + } + try + { + processAllTokens(sb, thisClass, method, field, version); + } + catch (AmqpTemplateException e) + { + System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); + } + } + + @Override + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) + { + if (token.compareTo("${GENERATOR}") == 0) + { + return GENERATOR_INFO; + } + if (token.compareTo("${CLASS}") == 0 && thisClass != null) + { + return thisClass.getName(); + } + if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) + { + if (version == null) + { + return String.valueOf(thisClass.getIndexMap().firstKey()); + } + return getIndex(thisClass.getIndexMap(), version); + } + if (token.compareTo("${METHOD}") == 0 && method != null) + { + return method.getName(); + } + if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) + { + if (version == null) + { + return String.valueOf(method.getIndexMap().firstKey()); + } + return getIndex(method.getIndexMap(), version); + } + if (token.compareTo("${FIELD}") == 0 && field != null) + { + return field.getName(); + } + if (token.compareTo(versionNamespaceStartToken) == 0 && version != null) + { + return "namespace " + version.namespace() + CR + "{"; + } + if (token.compareTo(versionNamespaceEndToken) == 0 && version != null) + { + return "} // namespace " + version.namespace(); + } if (token.compareTo("${mb_constructor_with_initializers}") == 0) + { return generateConstructor(thisClass, method, version, 4, 4); + } if (token.compareTo("${mb_server_operation_invoke}") == 0) + { return generateServerOperationsInvoke(thisClass, method, version, 4, 4); + } if (token.compareTo("${mb_buffer_param}") == 0) - return method.fieldMap.size() > 0 ? " buffer" : ""; + { + return method.getFieldMap().size() > 0 ? " buffer" : ""; + } if (token.compareTo("${hv_latest_major}") == 0) - return String.valueOf(globalVersionSet.last().getMajor()); + { + return String.valueOf(getVersionSet().last().getMajor()); + } if (token.compareTo("${hv_latest_minor}") == 0) - return String.valueOf(globalVersionSet.last().getMinor()); - - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - @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 tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // ClientOperations.h - if (token.compareTo("${coh_method_handler_get_method}") == 0) - { - codeSnippet = generateOpsMethodHandlerGetMethods(model, false, 4); - } - else if (token.compareTo("${coh_inner_class}") == 0) - { - codeSnippet = generateOpsInnerClasses(model, false, 4, 4); - } - - // ServerOperations.h - else if (token.compareTo("${soh_method_handler_get_method}") == 0) - { - codeSnippet = generateOpsMethodHandlerGetMethods(model, true, 4); - } - else if (token.compareTo("${soh_inner_class}") == 0) - { - codeSnippet = generateOpsInnerClasses(model, true, 4, 4); - } - - // ClientProxy.h/cpp - else if (token.compareTo("${cph_inner_class_instance}") == 0) - { - codeSnippet = generateProxyInnerClassInstances(model, false, 4); - } - else if (token.compareTo("${cph_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodDecls(model, false, 4); - } - else if (token.compareTo("${cph_inner_class_defn}") == 0) - { - codeSnippet = generateProxyInnerClassDefinitions(model, false, 4, 4); - } - else if (token.compareTo("${cpc_constructor_initializer}") == 0) - { - codeSnippet = generateProxyConstructorInitializers(model, false, 4); - } - else if (token.compareTo("${cpc_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodImpls(model, false, 0, 4); - } - else if (token.compareTo("${cpc_inner_class_impl}") == 0) - { - codeSnippet = generateProxyInnerClassImpl(model, false, 0, 4); - } + { + return String.valueOf(getVersionSet().last().getMinor()); + } + + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + @Override + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model, AmqpVersion version) + { + 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); + + // ClientOperations.h + if (token.compareTo("${coh_method_handler_get_method}") == 0) + { + codeSnippet = generateOpsMethodHandlerGetMethods(model, false, 4); + } + else if (token.compareTo("${coh_inner_class}") == 0) + { + codeSnippet = generateOpsInnerClasses(model, false, 4, 4); + } + + // ServerOperations.h + else if (token.compareTo("${soh_method_handler_get_method}") == 0) + { + codeSnippet = generateOpsMethodHandlerGetMethods(model, true, 4); + } + else if (token.compareTo("${soh_inner_class}") == 0) + { + codeSnippet = generateOpsInnerClasses(model, true, 4, 4); + } + + // ClientProxy.h/cpp + else if (token.compareTo("${cph_inner_class_instance}") == 0) + { + codeSnippet = generateProxyInnerClassInstances(model, false, 4); + } + else if (token.compareTo("${cph_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodDecls(model, false, 4); + } + else if (token.compareTo("${cph_inner_class_defn}") == 0) + { + codeSnippet = generateProxyInnerClassDefinitions(model, false, 4, 4); + } + else if (token.compareTo("${cpc_constructor_initializer}") == 0) + { + codeSnippet = generateProxyConstructorInitializers(model, false, 4); + } + else if (token.compareTo("${cpc_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodImpls(model, false, 0, 4); + } + else if (token.compareTo("${cpc_inner_class_impl}") == 0) + { + codeSnippet = generateProxyInnerClassImpl(model, false, 0, 4); + } else if (token.compareTo("${cph_handler_pointer_defn}") == 0) { codeSnippet = generateHandlerPointerDefinitions(model, false, 4); @@ -423,32 +443,32 @@ public class CppGenerator extends Generator { codeSnippet = generateHandlerPointerGetMethods(model, false, 4); } - - // SerrverProxy.h/cpp - else if (token.compareTo("${sph_inner_class_instance}") == 0) - { - codeSnippet = generateProxyInnerClassInstances(model, true, 4); - } - else if (token.compareTo("${sph_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodDecls(model, true, 4); - } - else if (token.compareTo("${sph_inner_class_defn}") == 0) - { - codeSnippet = generateProxyInnerClassDefinitions(model, true, 4, 4); - } - else if (token.compareTo("${spc_constructor_initializer}") == 0) - { - codeSnippet = generateProxyConstructorInitializers(model, true, 4); - } - else if (token.compareTo("${spc_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodImpls(model, true, 0, 4); - } - else if (token.compareTo("${spc_inner_class_impl}") == 0) - { - codeSnippet = generateProxyInnerClassImpl(model, true, 0, 4); - } + + // SerrverProxy.h/cpp + else if (token.compareTo("${sph_inner_class_instance}") == 0) + { + codeSnippet = generateProxyInnerClassInstances(model, true, 4); + } + else if (token.compareTo("${sph_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodDecls(model, true, 4); + } + else if (token.compareTo("${sph_inner_class_defn}") == 0) + { + codeSnippet = generateProxyInnerClassDefinitions(model, true, 4, 4); + } + else if (token.compareTo("${spc_constructor_initializer}") == 0) + { + codeSnippet = generateProxyConstructorInitializers(model, true, 4); + } + else if (token.compareTo("${spc_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodImpls(model, true, 0, 4); + } + else if (token.compareTo("${spc_inner_class_impl}") == 0) + { + codeSnippet = generateProxyInnerClassImpl(model, true, 0, 4); + } else if (token.compareTo("${sph_handler_pointer_defn}") == 0) { codeSnippet = generateHandlerPointerDefinitions(model, true, 4); @@ -457,7 +477,7 @@ public class CppGenerator extends Generator { codeSnippet = generateHandlerPointerGetMethods(model, true, 4); } - + // amqp_methods.h/cpp else if (token.compareTo("${mh_method_body_class_indlude}") == 0) { @@ -471,26 +491,25 @@ public class CppGenerator extends Generator { codeSnippet = generateMethodBodyMapEntry(model, 4); } - - 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 - { + + 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) + { String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + 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("${cpc_method_body_include}") == 0) { codeSnippet = generateMethodBodyIncludes(thisClass, 0); @@ -503,71 +522,68 @@ public class CppGenerator extends Generator { codeSnippet = generateMethodBodyIncludes(thisClass, 0); } - + + 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) + { + 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("${mb_field_declaration}") == 0) + { + codeSnippet = generateFieldDeclarations(fieldMap, version, 4); + } + else if (token.compareTo("${mb_field_get_method}") == 0) + { + codeSnippet = generateFieldGetMethods(fieldMap, version, 4); + } + else if (token.compareTo("${mb_field_print}") == 0) + { + codeSnippet = generatePrintMethodContents(fieldMap, version, 8); + } + else if (token.compareTo("${mb_body_size}") == 0) + { + codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8); + } + else if (token.compareTo("${mb_encode}") == 0) + { + codeSnippet = generateEncodeMethodContents(fieldMap, version, 8); + } + else if (token.compareTo("${mb_decode}") == 0) + { + codeSnippet = generateDecodeMethodContents(fieldMap, version, 8); + } + 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 tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - if (token.compareTo("${mb_field_declaration}") == 0) - { - codeSnippet = generateFieldDeclarations(fieldMap, version, 4); - } - else if (token.compareTo("${mb_field_get_method}") == 0) - { - codeSnippet = generateFieldGetMethods(fieldMap, version, 4); - } - else if (token.compareTo("${mb_field_print}") == 0) - { - codeSnippet = generatePrintMethodContents(fieldMap, version, 8); - } - else if (token.compareTo("${mb_body_size}") == 0) - { - codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8); - } - else if (token.compareTo("${mb_encode}") == 0) - { - codeSnippet = generateEncodeMethodContents(fieldMap, version, 8); - } - else if (token.compareTo("${mb_decode}") == 0) - { - codeSnippet = generateDecodeMethodContents(fieldMap, version, 8); - } - - 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 + AmqpConstantSet constantSet) { String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + 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("${ch_get_value_method}") == 0) { codeSnippet = generateConstantGetMethods(constantSet, 4, 4); @@ -579,36 +595,35 @@ public class CppGenerator extends Generator } sb.insert(listMarkerStartIndex, codeSnippet); } - - // === Protected and private helper functions unique to C++ implementation === - + + // === Protected and private helper functions unique to C++ implementation === + // Methods for generation of code snippets for AMQP_Constants.h file - + protected String generateConstantGetMethods(AmqpConstantSet constantSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - for (AmqpConstant thisConstant : constantSet) + for (AmqpConstant thisConstant : constantSet.getContstants()) { - if (thisConstant.isVersionConsistent(globalVersionSet)) + if (thisConstant.isVersionConsistent(getVersionSet())) { // return a constant String value = thisConstant.firstKey(); - sb.append(indent + "static const char* " + thisConstant.name + "() { return \"" + - thisConstant.firstKey() + "\"; }" + cr); + sb.append(indent + "static const char* " + thisConstant.getName() + "() { return \"" + + thisConstant.firstKey() + "\"; }" + CR); if (Utils.containsOnlyDigits(value)) { - sb.append(indent + "static int " + thisConstant.name + "AsInt() { return " + - thisConstant.firstKey() + "; }" + cr); + sb.append(indent + "static int " + thisConstant.getName() + "AsInt() { return " + + thisConstant.firstKey() + "; }" + CR); } if (Utils.containsOnlyDigitsAndDecimal(value)) { - sb.append(indent + "static double " + thisConstant.name + "AsDouble() { return (double)" + - thisConstant.firstKey() + "; }" + cr); + sb.append(indent + "static double " + thisConstant.getName() + "AsDouble() { return (double)" + + thisConstant.firstKey() + "; }" + CR); } - sb.append(cr); + sb.append(CR); } else { @@ -616,470 +631,502 @@ public class CppGenerator extends Generator sb.append(generateVersionDependentGet(thisConstant, "const char*", "", "\"", "\"", indentSize, tabSize)); sb.append(generateVersionDependentGet(thisConstant, "int", "AsInt", "", "", indentSize, tabSize)); sb.append(generateVersionDependentGet(thisConstant, "double", "AsDouble", "(double)", "", indentSize, tabSize)); - sb.append(cr); + sb.append(CR); } - } - return sb.toString(); + } + return sb.toString(); } - + protected String generateVersionDependentGet(AmqpConstant constant, String methodReturnType, - String methodNameSuffix, String returnPrefix, String returnPostfix, int indentSize, int tabSize) - throws AmqpTypeMappingException + String methodNameSuffix, String returnPrefix, String returnPostfix, int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - sb.append(indent + methodReturnType + " " + constant.name + methodNameSuffix + - "() const" + cr); - sb.append(indent + "{" + cr); + sb.append(indent + methodReturnType + " " + constant.getName() + methodNameSuffix + + "() const" + CR); + sb.append(indent + "{" + CR); boolean first = true; for (String thisValue : constant.keySet()) { AmqpVersionSet versionSet = constant.get(thisValue); sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) + - ")" + cr); - sb.append(indent + tab + "{" + cr); + ")" + CR); + sb.append(indent + tab + "{" + CR); if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(thisValue)) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); } else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(thisValue)) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); } else { - sb.append(indent + tab + tab + "return " + returnPrefix + thisValue + returnPostfix + ";" + cr); + sb.append(indent + tab + tab + "return " + returnPrefix + thisValue + returnPostfix + ";" + CR); } - sb.append(indent + tab + "}" + cr); + sb.append(indent + tab + "}" + CR); first = false; } - sb.append(indent + tab + "else" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "std::stringstream ss;" + cr); - sb.append(indent + tab + tab + "ss << \"Constant \\\"" + constant.name + - "\\\" is undefined for AMQP version \" <<" + cr); - sb.append(indent + tab + tab + tab + "version.toString() << \".\";" + cr); - sb.append(indent + tab + tab + "throw ProtocolVersionException(ss.str());" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + "}" + cr); - return sb.toString(); - } - + sb.append(indent + tab + "else" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "std::stringstream ss;" + CR); + sb.append(indent + tab + tab + "ss << \"Constant \\\"" + constant.getName() + + "\\\" is undefined for AMQP version \" <<" + CR); + sb.append(indent + tab + tab + tab + "version.toString() << \".\";" + CR); + sb.append(indent + tab + tab + "throw ProtocolVersionException(ss.str());" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + "}" + CR); + return sb.toString(); + } + protected String generateConstantDeclarationException(String name, String methodReturnType, - int indentSize, int tabSize) + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - sb.append(indent + "std::stringstream ss;" + cr); + sb.append(indent + "std::stringstream ss;" + CR); sb.append(indent + "ss << \"Constant \\\"" + name + "\\\" cannot be converted to type " + - methodReturnType + " for AMQP version \" <<" + cr); - sb.append(indent + tab + "version.toString() << \".\";" + cr); - sb.append(indent + "throw ProtocolVersionException(ss.str());" + cr); - return sb.toString(); - } - - // Methods used for generation of code snippets for Server/ClientOperations class generation - - protected String generateOpsMethodHandlerGetMethods(AmqpModel model, boolean serverFlag, int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - // Only generate for this class if there is at least one method of the - // required chassis (server/client flag). - boolean chassisFoundFlag = false; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - chassisFoundFlag = true; - } - if (chassisFoundFlag) - { - sb.append(indent + "virtual AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + - thisClass.name + "Handler* get" + thisClass.name + "Handler() = 0;" + cr); - } - } - return sb.toString(); - } - - protected String generateOpsInnerClasses(AmqpModel model, boolean serverFlag, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - - String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String handlerClassName = thisClass.name + "Handler"; - if (!first) - sb.append(cr); - sb.append(indent + "// ==================== class " + handlerClassName + - " ====================" + cr); - sb.append(indent + "class " + handlerClassName); - 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 + proxyClassName+ "* parent;" + cr); - sb.append(cr); - sb.append(indent + tab + "// Constructors and destructors" + cr); - sb.append(cr); - sb.append(indent + "protected:" + cr); - sb.append(indent + tab + handlerClassName + "() {}" + cr); - sb.append(indent + "public:" + cr); - sb.append(indent + tab + handlerClassName + - "(" + proxyClassName + "* _parent) {parent = _parent;}" + cr); - sb.append(indent + tab + "virtual ~" + handlerClassName + "() {}" + cr); - sb.append(cr); - sb.append(indent + tab + "// Protocol methods" + cr); - sb.append(cr); - sb.append(generateInnerClassMethods(thisClass, serverFlag, true, indentSize + tabSize, tabSize)); - sb.append(indent + "}; // class " + handlerClassName + cr); - first = false; - } - return sb.toString(); - } - - protected String generateInnerClassMethods(AmqpClass thisClass, boolean serverFlag, - boolean abstractMethodFlag, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + (abstractMethodFlag ? "Operations" : "Proxy"); - boolean first = true; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - { - String methodName = parseForReservedWords(method.name, outerClassName + "." + thisClass.name); - AmqpOverloadedParameterMap overloadededParameterMap = - method.getOverloadedParameterLists(thisClass.versionSet, this); - for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) - { - AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); - if (!first) - sb.append(cr); - sb.append(indent + "virtual void " + methodName + "( u_int16_t channel"); - sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5*tabSize), true, true, true)); - sb.append(" )"); - if (abstractMethodFlag) - sb.append(" = 0"); - sb.append(";"); - if (versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + versionSet); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - // Methods used for generation of code snippets for Server/ClientProxy class generation + methodReturnType + " for AMQP version \" <<" + CR); + sb.append(indent + tab + "version.toString() << \".\";" + CR); + sb.append(indent + "throw ProtocolVersionException(ss.str());" + CR); + return sb.toString(); + } + + // Methods used for generation of code snippets for Server/ClientOperations class generation + + protected String generateOpsMethodHandlerGetMethods(AmqpModel model, boolean serverFlag, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + // Only generate for this class if there is at least one method of the + // required chassis (server/client flag). + boolean chassisFoundFlag = false; + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + boolean clientChassisFlag = method.getClientMethodFlagMap().isSet(); + boolean serverChassisFlag = method.getServerMethodFlagMap().isSet(); + if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) + { + chassisFoundFlag = true; + } + } + if (chassisFoundFlag) + { + sb.append(indent + "virtual AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + + thisClass.getName() + "Handler* get" + thisClass.getName() + "Handler() = 0;" + CR); + } + } + return sb.toString(); + } + + protected String generateOpsInnerClasses(AmqpModel model, boolean serverFlag, int indentSize, int tabSize) + { + + String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String handlerClassName = thisClass.getName() + "Handler"; + if (!first) + { + sb.append(CR); + } + sb.append(indent + "// ==================== class " + handlerClassName + + " ====================" + CR); + sb.append(indent + "class " + handlerClassName); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + sb.append(indent + "{" + CR); + sb.append(indent + "private:" + CR); + sb.append(indent + tab + proxyClassName + "* parent;" + CR); + sb.append(CR); + sb.append(indent + tab + "// Constructors and destructors" + CR); + sb.append(CR); + sb.append(indent + "protected:" + CR); + sb.append(indent + tab + handlerClassName + "() {}" + CR); + sb.append(indent + "public:" + CR); + sb.append(indent + tab + handlerClassName + + "(" + proxyClassName + "* _parent) {parent = _parent;}" + CR); + sb.append(indent + tab + "virtual ~" + handlerClassName + "() {}" + CR); + sb.append(CR); + sb.append(indent + tab + "// Protocol methods" + CR); + sb.append(CR); + sb.append(generateInnerClassMethods(thisClass, serverFlag, true, indentSize + tabSize, tabSize)); + sb.append(indent + "}; // class " + handlerClassName + CR); + first = false; + } + return sb.toString(); + } + + protected String generateInnerClassMethods(AmqpClass thisClass, boolean serverFlag, + boolean abstractMethodFlag, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + (abstractMethodFlag ? "Operations" + : "Proxy"); + boolean first = true; + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + boolean clientChassisFlag = method.getClientMethodFlagMap().isSet(); + boolean serverChassisFlag = method.getServerMethodFlagMap().isSet(); + if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) + { + String methodName = parseForReservedWords(method.getName(), outerClassName + "." + thisClass.getName()); + AmqpOverloadedParameterMap overloadededParameterMap = + method.getOverloadedParameterLists(thisClass.getVersionSet(), this); + for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) + { + AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); + if (!first) + { + sb.append(CR); + } + sb.append(indent + "virtual void " + methodName + "( u_int16_t channel"); + sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5 * tabSize), true, true, true)); + sb.append(" )"); + if (abstractMethodFlag) + { + sb.append(" = 0"); + } + sb.append(";"); + if (versionSet.size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + versionSet); + } + sb.append(CR); + first = false; + } + } + } + return sb.toString(); + } + + // Methods used for generation of code snippets for Server/ClientProxy class generation protected String generateHandlerPointerDefinitions(AmqpModel model, boolean serverFlag, - int indentSize) + int indentSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; - for (String thisClassName : model.classMap.keySet()) + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - sb.append(indent + outerClassName + "::" + thisClass.name + "Handler* " + - thisClass.name + "HandlerPtr;" + cr); + AmqpClass thisClass = model.getClassMap().get(thisClassName); + sb.append(indent + outerClassName + "::" + thisClass.getName() + "Handler* " + + thisClass.getName() + "HandlerPtr;" + CR); } return sb.toString(); } - + protected String generateHandlerPointerGetMethods(AmqpModel model, boolean serverFlag, - int indentSize) + int indentSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; - for (String thisClassName : model.classMap.keySet()) + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - sb.append(indent + "virtual inline " + outerClassName + "::" + thisClass.name + "Handler* get" + - thisClass.name + "Handler() { return &" + Utils.firstLower(thisClass.name) + ";}" + cr); + AmqpClass thisClass = model.getClassMap().get(thisClassName); + sb.append(indent + "virtual inline " + outerClassName + "::" + thisClass.getName() + "Handler* get" + + thisClass.getName() + "Handler() { return &" + Utils.firstLower(thisClass.getName()) + ";}" + CR); } return sb.toString(); - } - - protected String generateProxyInnerClassInstances(AmqpModel model, boolean serverFlag, - int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); + } + + protected String generateProxyInnerClassInstances(AmqpModel model, boolean serverFlag, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String instanceName = parseForReservedWords(Utils.firstLower(thisClass.name), outerClassName); - String className = parseForReservedWords(thisClass.name, null); - sb.append(indent + className + " " + instanceName + ";"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassGetMethodDecls(AmqpModel model, boolean serverFlag, - int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName); + String className = parseForReservedWords(thisClass.getName(), null); + sb.append(indent + className + " " + instanceName + ";"); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassGetMethodDecls(AmqpModel model, boolean serverFlag, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = parseForReservedWords(thisClass.name, outerClassName); - sb.append(indent + className + "& get" + className + "();"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassDefinitions(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = thisClass.name; - String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + - thisClass.name + "Handler"; - if (!first) - sb.append(cr); - sb.append(indent + "// ==================== class " + className + - " ====================" + cr); - sb.append(indent + "class " + className + " : virtual public " + superclassName); - 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 + "OutputHandler* out;" + cr); - sb.append(indent + tab + proxyClassName + "* parent;" + 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 + "(OutputHandler* out, " + proxyClassName + "* _parent) : " + cr); - sb.append(indent + tab + tab + "out(out) {parent = _parent;}" + 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, serverFlag, false, indentSize + tabSize, tabSize)); - sb.append(indent + "}; // class " + className + cr); - first = false; - } - return sb.toString(); - } - - protected String generateProxyConstructorInitializers(AmqpModel model, boolean serverFlag, - int indentSize) - { + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String className = parseForReservedWords(thisClass.getName(), outerClassName); + sb.append(indent + className + "& get" + className + "();"); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassDefinitions(AmqpModel model, boolean serverFlag, + int indentSize, int tabSize) + { + String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String className = thisClass.getName(); + String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + + thisClass.getName() + "Handler"; + if (!first) + { + sb.append(CR); + } + sb.append(indent + "// ==================== class " + className + + " ====================" + CR); + sb.append(indent + "class " + className + " : virtual public " + superclassName); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + sb.append(indent + "{" + CR); + sb.append(indent + "private:" + CR); + sb.append(indent + tab + "OutputHandler* out;" + CR); + sb.append(indent + tab + proxyClassName + "* parent;" + 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 + "(OutputHandler* out, " + proxyClassName + "* _parent) : " + CR); + sb.append(indent + tab + tab + "out(out) {parent = _parent;}" + 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, serverFlag, false, indentSize + tabSize, tabSize)); + sb.append(indent + "}; // class " + className + CR); + first = false; + } + return sb.toString(); + } + + protected String generateProxyConstructorInitializers(AmqpModel model, boolean serverFlag, + int indentSize) + { String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(indent + superclassName + "(major, minor)," + cr); - sb.append(indent + "version(major, minor)," + cr); + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(indent + superclassName + "(major, minor)," + CR); + sb.append(indent + "version(major, minor)," + CR); sb.append(indent + "out(out)"); - Iterator<String> cItr = model.classMap.keySet().iterator(); - while (cItr.hasNext()) - { - AmqpClass thisClass = model.classMap.get(cItr.next()); - String instanceName = parseForReservedWords(Utils.firstLower(thisClass.name), outerClassName); - sb.append("," + cr); - sb.append(indent + instanceName + "(out, this)"); - if (!cItr.hasNext()) - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassGetMethodImpls(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - Iterator<String> cItr = model.classMap.keySet().iterator(); - while (cItr.hasNext()) - { - AmqpClass thisClass = model.classMap.get(cItr.next()); - String className = thisClass.name; - String instanceName = parseForReservedWords(Utils.firstLower(thisClass.name), outerClassName); - sb.append(indent + outerClassName + "::" + className + "& " + - outerClassName + "::get" + className + "()" + cr); - sb.append(indent + "{" + cr); - if (thisClass.versionSet.size() != globalVersionSet.size()) - { - sb.append(indent + tab + "if (!" + generateVersionCheck(thisClass.versionSet) + ")" + cr); - sb.append(indent + tab + tab + "throw new ProtocolVersionException();" + cr); - } - sb.append(indent + tab + "return " + instanceName + ";" + cr); - sb.append(indent + "}" + cr); - if (cItr.hasNext()) - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassImpl(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - boolean firstClassFlag = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = thisClass.name; - if (!firstClassFlag) - sb.append(cr); - sb.append(indent + "// ==================== class " + className + - " ====================" + cr); - sb.append(generateInnerClassMethodImpls(thisClass, serverFlag, indentSize, tabSize)); - firstClassFlag = false; - } - return sb.toString(); - } - - protected String generateInnerClassMethodImpls(AmqpClass thisClass, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - boolean first = true; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String methodBodyClassName = thisClass.name + Utils.firstUpper(method.name) + "Body"; - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - boolean versionConsistentFlag = method.isVersionConsistent(globalVersionSet); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - { - String methodName = parseForReservedWords(method.name, outerclassName + "." + thisClass.name); - AmqpOverloadedParameterMap overloadededParameterMap = - method.getOverloadedParameterLists(thisClass.versionSet, this); - for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) - { - AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); - if (!first) - sb.append(cr); - sb.append(indent + "void " + outerclassName + "::" + thisClass.name + "::" + - methodName + "( u_int16_t channel"); - sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5*tabSize), true, true, true)); - sb.append(" )"); - if (versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + versionSet); - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(generateMethodBodyCallContext(thisFieldMap, outerclassName, methodBodyClassName, - versionConsistentFlag, versionSet, indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - protected String generateMethodBodyCallContext(AmqpOrdinalFieldMap fieldMap, String outerclassName, - String methodBodyClassName, boolean versionConsistentFlag, AmqpVersionSet versionSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - if (versionConsistentFlag) - { - sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, null, indentSize, tabSize)); - } - else - { - boolean firstOverloadedMethodFlag = true; - for (AmqpVersion thisVersion : versionSet) - { - sb.append(indent); - if (!firstOverloadedMethodFlag) - sb.append("else "); - sb.append("if (" + generateVersionCheck(thisVersion) + ")" + cr); - sb.append(indent + "{" + cr); - sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, thisVersion, - indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - firstOverloadedMethodFlag = false; - } - sb.append(indent + "else" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "std::stringstream ss;" + cr); - sb.append(indent + tab + "ss << \"Call to " + outerclassName + "::" + methodBodyClassName + - "(u_int16_t" + generateMethodParameterList(fieldMap, 0, true, true, false) + ")\"" + cr); - sb.append(indent + tab + tab + "<< \" is invalid for AMQP version \" << version.toString() << \".\";" + cr); - sb.append(indent + tab + "throw new ProtocolVersionException(ss.str());" + cr); - sb.append(indent + "}" + cr); - } - return sb.toString(); - } - - protected String generateMethodBodyCall(AmqpOrdinalFieldMap fieldMap, String methodBodyClassName, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String namespace = version != null ? version.namespace() + "::" : ""; - StringBuffer sb = new StringBuffer(indent + "out->send( new AMQFrame(parent->getProtocolVersion(), channel," + cr); - sb.append(indent + tab + "new " + namespace + methodBodyClassName + "( parent->getProtocolVersion()"); - sb.append(generateMethodParameterList(fieldMap, indentSize + (5*tabSize), true, false, true)); - sb.append(" )));" + cr); - return sb.toString(); - } - + Iterator<String> cItr = model.getClassMap().keySet().iterator(); + while (cItr.hasNext()) + { + AmqpClass thisClass = model.getClassMap().get(cItr.next()); + String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName); + sb.append("," + CR); + sb.append(indent + instanceName + "(out, this)"); + if (!cItr.hasNext()) + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassGetMethodImpls(AmqpModel model, boolean serverFlag, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + Iterator<String> cItr = model.getClassMap().keySet().iterator(); + while (cItr.hasNext()) + { + AmqpClass thisClass = model.getClassMap().get(cItr.next()); + String className = thisClass.getName(); + String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName); + sb.append(indent + outerClassName + "::" + className + "& " + + outerClassName + "::get" + className + "()" + CR); + sb.append(indent + "{" + CR); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(indent + tab + "if (!" + generateVersionCheck(thisClass.getVersionSet()) + ")" + CR); + sb.append(indent + tab + tab + "throw new ProtocolVersionException();" + CR); + } + sb.append(indent + tab + "return " + instanceName + ";" + CR); + sb.append(indent + "}" + CR); + if (cItr.hasNext()) + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassImpl(AmqpModel model, boolean serverFlag, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + boolean firstClassFlag = true; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String className = thisClass.getName(); + if (!firstClassFlag) + { + sb.append(CR); + } + sb.append(indent + "// ==================== class " + className + + " ====================" + CR); + sb.append(generateInnerClassMethodImpls(thisClass, serverFlag, indentSize, tabSize)); + firstClassFlag = false; + } + return sb.toString(); + } + + protected String generateInnerClassMethodImpls(AmqpClass thisClass, boolean serverFlag, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + boolean first = true; + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + String methodBodyClassName = thisClass.getName() + Utils.firstUpper(method.getName()) + "Body"; + boolean clientChassisFlag = method.getClientMethodFlagMap().isSet(); + boolean serverChassisFlag = method.getServerMethodFlagMap().isSet(); + boolean versionConsistentFlag = method.isVersionConsistent(getVersionSet()); + if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) + { + String methodName = parseForReservedWords(method.getName(), outerclassName + "." + thisClass.getName()); + AmqpOverloadedParameterMap overloadededParameterMap = + method.getOverloadedParameterLists(thisClass.getVersionSet(), this); + for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) + { + AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); + if (!first) + { + sb.append(CR); + } + sb.append(indent + "void " + outerclassName + "::" + thisClass.getName() + "::" + + methodName + "( u_int16_t channel"); + sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5 * tabSize), true, true, true)); + sb.append(" )"); + if (versionSet.size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + versionSet); + } + sb.append(CR); + sb.append(indent + "{" + CR); + sb.append(generateMethodBodyCallContext(thisFieldMap, outerclassName, methodBodyClassName, + versionConsistentFlag, versionSet, indentSize + tabSize, tabSize)); + sb.append(indent + "}" + CR); + sb.append(CR); + first = false; + } + } + } + return sb.toString(); + } + + protected String generateMethodBodyCallContext(AmqpOrdinalFieldMap fieldMap, String outerclassName, + String methodBodyClassName, boolean versionConsistentFlag, AmqpVersionSet versionSet, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + if (versionConsistentFlag) + { + sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, null, indentSize, tabSize)); + } + else + { + boolean firstOverloadedMethodFlag = true; + for (AmqpVersion thisVersion : versionSet) + { + sb.append(indent); + if (!firstOverloadedMethodFlag) + { + sb.append("else "); + } + sb.append("if (" + generateVersionCheck(thisVersion) + ")" + CR); + sb.append(indent + "{" + CR); + sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, thisVersion, + indentSize + tabSize, tabSize)); + sb.append(indent + "}" + CR); + firstOverloadedMethodFlag = false; + } + sb.append(indent + "else" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "std::stringstream ss;" + CR); + sb.append(indent + tab + "ss << \"Call to " + outerclassName + "::" + methodBodyClassName + + "(u_int16_t" + generateMethodParameterList(fieldMap, 0, true, true, false) + ")\"" + CR); + sb.append(indent + tab + tab + "<< \" is invalid for AMQP version \" << version.toString() << \".\";" + CR); + sb.append(indent + tab + "throw new ProtocolVersionException(ss.str());" + CR); + sb.append(indent + "}" + CR); + } + return sb.toString(); + } + + protected String generateMethodBodyCall(AmqpOrdinalFieldMap fieldMap, String methodBodyClassName, + AmqpVersion version, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String namespace = version != null ? version.namespace() + "::" : ""; + StringBuffer sb = new StringBuffer(indent + "out->send( new AMQFrame(parent->getProtocolVersion(), channel," + CR); + sb.append(indent + tab + "new " + namespace + methodBodyClassName + "( parent->getProtocolVersion()"); + sb.append(generateMethodParameterList(fieldMap, indentSize + (5 * tabSize), true, false, true)); + sb.append(" )));" + CR); + return sb.toString(); + } + protected String generateMethodBodyIncludes(AmqpClass thisClass, int indentSize) { StringBuffer sb = new StringBuffer(); @@ -1089,86 +1136,90 @@ public class CppGenerator extends Generator } else { - for (String thisClassName : model.classMap.keySet()) + for (String thisClassName : getModel().getClassMap().keySet()) { - thisClass = model.classMap.get(thisClassName); + thisClass = getModel().getClassMap().get(thisClassName); sb.append(generateClassMethodBodyInclude(thisClass, indentSize)); - } + } } - return sb.toString(); + return sb.toString(); } - + protected String generateClassMethodBodyInclude(AmqpClass thisClass, int indentSize) { StringBuffer sb = new StringBuffer(); String indent = Utils.createSpaces(indentSize); - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "#include <" + thisClass.name + - Utils.firstUpper(method.name) + "Body.h>" + cr); - } - return sb.toString(); - } - - // Methods used for generation of code snippets for MethodBody class generation - - protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) - throws AmqpTemplateException - { - for (Integer thisIndex : indexMap.keySet()) - { - AmqpVersionSet versionSet = indexMap.get(thisIndex); - if (versionSet.contains(version)) - return String.valueOf(thisIndex); - } - throw new AmqpTemplateException("Unable to find index for version " + version); - } - - protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + sb.append(indent + "#include <" + thisClass.getName() + + Utils.firstUpper(method.getName()) + "Body.h>" + CR); + } + return sb.toString(); + } + + // Methods used for generation of code snippets for MethodBody class generation + + protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) + { + for (Integer thisIndex : indexMap.keySet()) + { + AmqpVersionSet versionSet = indexMap.get(thisIndex); + if (versionSet.contains(version)) + { + return String.valueOf(thisIndex); + } + } + throw new AmqpTemplateException("Unable to find index for version " + version); + } + + protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + if (version == null) - version = globalVersionSet.first(); + { + version = getVersionSet().first(); + } AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); for (Integer thisOrdinal : ordinalFieldMap.keySet()) { String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal); - sb.append(indent + fieldDomainPair[FIELD_CODE_TYPE] + " " + fieldDomainPair[FIELD_NAME] + ";" + cr); - } - return sb.toString(); - } - - protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - + sb.append(indent + fieldDomainPair[FIELD_CODE_TYPE] + " " + fieldDomainPair[FIELD_NAME] + ";" + CR); + } + return sb.toString(); + } + + protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + if (version == null) - version = globalVersionSet.first(); + { + version = getVersionSet().first(); + } AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); for (Integer thisOrdinal : ordinalFieldMap.keySet()) { String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal); - sb.append(indent + "inline " + setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " get" + - Utils.firstUpper(fieldDomainPair[FIELD_NAME]) + "() { return " + - fieldDomainPair[FIELD_NAME] + "; }" + cr); - } - return sb.toString(); - } - - protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - + sb.append(indent + "inline " + setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " get" + + Utils.firstUpper(fieldDomainPair[FIELD_NAME]) + "() { return " + + fieldDomainPair[FIELD_NAME] + "; }" + CR); + } + return sb.toString(); + } + + protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + if (version == null) - version = globalVersionSet.first(); + { + version = getVersionSet().first(); + } AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); boolean firstFlag = true; for (Integer thisOrdinal : ordinalFieldMap.keySet()) @@ -1177,452 +1228,489 @@ public class CppGenerator extends Generator String cast = fieldDomainPair[FIELD_CODE_TYPE].compareTo("u_int8_t") == 0 ? "(int)" : ""; sb.append(indent + "out << \""); if (!firstFlag) + { sb.append("; "); - sb.append(fieldDomainPair[FIELD_NAME] + "=\" << " + cast + fieldDomainPair[FIELD_NAME] + ";" + cr); + } + sb.append(fieldDomainPair[FIELD_NAME] + "=\" << " + cast + fieldDomainPair[FIELD_NAME] + ";" + CR); firstFlag = false; } - return sb.toString(); - } - - protected String generateBodySizeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, - int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList<String> bitFieldList = new ArrayList<String>(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); - Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); - int ordinal = 0; - while (oItr.hasNext()) - { - ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; - String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); - - // Defer bit types by adding them to an array. When the first subsequent non-bit - // type is encountered, then handle the bits. This allows consecutive bits to be - // placed into the same byte(s) - 8 bits to the byte. - if (domainType.compareTo("bit") == 0) - { - bitFieldList.add(fieldDomainPair[FIELD_NAME]); - } - else - { - if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) - { - sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); - } - sb.append(indent + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldDomainPair[FIELD_NAME]) + - "; /* " + fieldDomainPair[FIELD_NAME] + ": " + - domainType + " */" + cr); - } - } - if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types - { - sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); - } - return sb.toString(); - } - - protected String generateBitArrayBodySizeMethodContents(ArrayList<String> bitFieldList, - int ordinal, int indentSize) - { - int numBytes = ((bitFieldList.size() - 1) / 8) + 1; - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - sb.append(indent + "size += " + - typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + - "; /* " + comment + " */" + cr); - bitFieldList.clear(); - return sb.toString(); - } - - protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, - int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList<String> bitFieldList = new ArrayList<String>(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); - Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); - int ordinal = 0; - while (oItr.hasNext()) - { - ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; - String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); - - // Defer bit types by adding them to an array. When the first subsequent non-bit - // type is encountered, then handle the bits. This allows consecutive bits to be - // placed into the same byte(s) - 8 bits to the byte. - if (domainType.compareTo("bit") == 0) - { - bitFieldList.add(fieldDomainPair[FIELD_NAME]); - } - else - { - if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) - { - sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); - } - sb.append(indent + - typeMap.get(domainType).encodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + - "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */"+ cr); - } - } - if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types - { - sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); - } - - return sb.toString(); - } - - protected String generateBitEncodeMethodContents(ArrayList<String> bitFieldList, int ordinal, - int indentSize) - { - int numBytes = ((bitFieldList.size() - 1) / 8) + 1; - String indent = Utils.createSpaces(indentSize); - String bitArrayName = "flags_" + ordinal; - StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName + - "[" + numBytes + "] = {0};" + - (numBytes != 1 ? " /* All array elements will be initialized to 0 */" : "") + - cr); - for (int i=0; i<bitFieldList.size(); i++) - { - int bitIndex = i%8; - int byteIndex = i/8; - sb.append(indent + bitArrayName + "[" + byteIndex + "] |= " + bitFieldList.get(i) + - " << " + bitIndex + "; /* " + bitFieldList.get(i) + ": bit */" + cr); - } - for (int i=0; i<numBytes; i++) - { - sb.append(indent + "buffer.putOctet(" + bitArrayName + "[" + i + "]);" + cr); - } - bitFieldList.clear(); - return sb.toString(); - } - - protected String generateDecodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, - int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList<String> bitFieldList = new ArrayList<String>(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); - Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); - int ordinal = 0; - while (oItr.hasNext()) - { - ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; - String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); - - // Defer bit types by adding them to an array. When the first subsequent non-bit - // type is encountered, then handle the bits. This allows consecutive bits to be - // placed into the same byte(s) - 8 bits to the byte. - if (domainType.compareTo("bit") == 0) - { - bitFieldList.add(fieldDomainPair[FIELD_NAME]); - } - else - { - if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) - { - sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); - } - sb.append(indent + - typeMap.get(domainType).decodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + - "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + cr); - } - } - if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types - { - sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); - } - - return sb.toString(); - } - - protected String generateBitDecodeMethodContents(ArrayList<String> bitFieldList, int ordinal, - int indentSize) - { - int numBytes = ((bitFieldList.size() - 1) / 8) + 1; - String indent = Utils.createSpaces(indentSize); - String bitArrayName = "flags_" + ordinal; - StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName + - "[" + numBytes + "];" + cr); - for (int i=0; i<numBytes; i++) - { - sb.append(indent + bitArrayName + "[" + i + "] = buffer.getOctet();" + cr); - } - for (int i=0; i<bitFieldList.size(); i++) - { - int bitIndex = i%8; - int byteIndex = i/8; - sb.append(indent + bitFieldList.get(i) + " = (1 << " + bitIndex + ") & " + - bitArrayName + "[" + byteIndex + "]; /* " + bitFieldList.get(i) + - ": bit */" + cr); - } - bitFieldList.clear(); - return sb.toString(); - } - - protected String generateFieldList(AmqpFieldMap fieldMap, AmqpVersion version, boolean defineFlag, - boolean initializerFlag, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); - Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - sb.append(indent + (defineFlag ? setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " " : "") + - fieldDomainPair[FIELD_NAME] + (initializerFlag ? "(" + fieldDomainPair[FIELD_NAME] + ")" : "") + - (oItr.hasNext() ? "," : "") + cr); - } - return sb.toString(); - } - - protected String generateMethodParameterList(AmqpOrdinalFieldMap fieldMap, int indentSize, - boolean leadingCommaFlag, boolean fieldTypeFlag, boolean fieldNameFlag) - 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()); - if (first && leadingCommaFlag) - { - sb.append("," + (fieldNameFlag ? cr : " ")); - } - if (!first || leadingCommaFlag) - { - sb.append(indent); - } - sb.append( - (fieldTypeFlag ? setRef(field[FIELD_CODE_TYPE]) : "") + - (fieldNameFlag ? " " + field[FIELD_NAME] : "") + - (pItr.hasNext() ? "," + (fieldNameFlag ? cr : " ") : "")); - first = false; - } - return sb.toString(); - } - + return sb.toString(); + } + + protected String generateBodySizeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + ArrayList<String> bitFieldList = new ArrayList<String>(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) + { + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? getVersionSet().first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); + + // Defer bit types by adding them to an array. When the first subsequent non-bit + // type is encountered, then handle the bits. This allows consecutive bits to be + // placed into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + + domainType + " */" + CR); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); + } + return sb.toString(); + } + + protected String generateBitArrayBodySizeMethodContents(ArrayList<String> bitFieldList, + int ordinal, int indentSize) + { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + sb.append(indent + "size += " + + typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + + "; /* " + comment + " */" + CR); + bitFieldList.clear(); + return sb.toString(); + } + + protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + ArrayList<String> bitFieldList = new ArrayList<String>(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) + { + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? getVersionSet().first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); + + // Defer bit types by adding them to an array. When the first subsequent non-bit + // type is encountered, then handle the bits. This allows consecutive bits to be + // placed into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + + typeMap.get(domainType).encodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + CR); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); + } + + return sb.toString(); + } + + protected String generateBitEncodeMethodContents(ArrayList<String> bitFieldList, int ordinal, + int indentSize) + { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + String bitArrayName = "flags_" + ordinal; + StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName + + "[" + numBytes + "] = {0};" + + (numBytes != 1 ? " /* All array elements will be initialized to 0 */" : "") + + CR); + for (int i = 0; i < bitFieldList.size(); i++) + { + int bitIndex = i % 8; + int byteIndex = i / 8; + sb.append(indent + bitArrayName + "[" + byteIndex + "] |= " + bitFieldList.get(i) + + " << " + bitIndex + "; /* " + bitFieldList.get(i) + ": bit */" + CR); + } + for (int i = 0; i < numBytes; i++) + { + sb.append(indent + "buffer.putOctet(" + bitArrayName + "[" + i + "]);" + CR); + } + bitFieldList.clear(); + return sb.toString(); + } + + protected String generateDecodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + ArrayList<String> bitFieldList = new ArrayList<String>(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + int ordinal = 0; + while (oItr.hasNext()) + { + ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + AmqpVersion thisVersion = version == null ? getVersionSet().first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); + + // Defer bit types by adding them to an array. When the first subsequent non-bit + // type is encountered, then handle the bits. This allows consecutive bits to be + // placed into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + + typeMap.get(domainType).decodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + CR); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); + } + + return sb.toString(); + } + + protected String generateBitDecodeMethodContents(ArrayList<String> bitFieldList, int ordinal, + int indentSize) + { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + String bitArrayName = "flags_" + ordinal; + StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName + + "[" + numBytes + "];" + CR); + for (int i = 0; i < numBytes; i++) + { + sb.append(indent + bitArrayName + "[" + i + "] = buffer.getOctet();" + CR); + } + for (int i = 0; i < bitFieldList.size(); i++) + { + int bitIndex = i % 8; + int byteIndex = i / 8; + sb.append(indent + bitFieldList.get(i) + " = (1 << " + bitIndex + ") & " + + bitArrayName + "[" + byteIndex + "]; /* " + bitFieldList.get(i) + + ": bit */" + CR); + } + bitFieldList.clear(); + return sb.toString(); + } + + protected String generateFieldList(AmqpFieldMap fieldMap, AmqpVersion version, boolean defineFlag, + boolean initializerFlag, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); + Iterator<Integer> oItr = ordinalFieldMap.keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + sb.append(indent + (defineFlag ? setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " " : "") + + fieldDomainPair[FIELD_NAME] + (initializerFlag ? "(" + fieldDomainPair[FIELD_NAME] + ")" : "") + + (oItr.hasNext() ? "," : "") + CR); + } + return sb.toString(); + } + + protected String generateMethodParameterList(AmqpOrdinalFieldMap fieldMap, int indentSize, + boolean leadingCommaFlag, boolean fieldTypeFlag, boolean fieldNameFlag) + { + 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()); + if (first && leadingCommaFlag) + { + sb.append("," + (fieldNameFlag ? CR : " ")); + } + if (!first || leadingCommaFlag) + { + sb.append(indent); + } + sb.append( + (fieldTypeFlag ? setRef(field[FIELD_CODE_TYPE]) : "") + + (fieldNameFlag ? " " + field[FIELD_NAME] : "") + + (pItr.hasNext() ? "," + (fieldNameFlag ? CR : " ") : "")); + first = false; + } + return sb.toString(); + } + protected String generateConstructor(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException + AmqpVersion version, int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - if (method.fieldMap.size() > 0) - { - sb.append(indent + thisClass.name + Utils.firstUpper(method.name) + "Body(ProtocolVersion& version," + cr); - sb.append(generateFieldList(method.fieldMap, version, true, false, 8)); - sb.append(indent + tab + ") :" + cr); - sb.append(indent + tab + "AMQMethodBody(version)," + cr); - sb.append(generateFieldList(method.fieldMap, version, false, true, 8)); - sb.append(indent + "{ }" + cr); - } - return sb.toString(); - } - + if (method.getFieldMap().size() > 0) + { + sb.append(indent + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body(ProtocolVersion& version," + CR); + sb.append(generateFieldList(method.getFieldMap(), version, true, false, 8)); + sb.append(indent + tab + ") :" + CR); + sb.append(indent + tab + "AMQMethodBody(version)," + CR); + sb.append(generateFieldList(method.getFieldMap(), version, false, true, 8)); + sb.append(indent + "{ }" + CR); + } + return sb.toString(); + } + protected String generateServerOperationsInvoke(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException + AmqpVersion version, int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - - if (method.serverMethodFlagMap.size() > 0) // At least one AMQP version defines this method as a server method + + if (method.getServerMethodFlagMap().size() > 0) // At least one AMQP version defines this method as a server method { - Iterator<Boolean> bItr = method.serverMethodFlagMap.keySet().iterator(); + Iterator<Boolean> bItr = method.getServerMethodFlagMap().keySet().iterator(); while (bItr.hasNext()) { if (bItr.next()) // This is a server operation { - boolean fieldMapNotEmptyFlag = method.fieldMap.size() > 0; - sb.append(indent + "inline void invoke(AMQP_ServerOperations& target, u_int16_t channel)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "target.get" + thisClass.name + "Handler()->" + - parseForReservedWords(Utils.firstLower(method.name), - thisClass.name + Utils.firstUpper(method.name) + "Body.invoke()") + "(channel"); + boolean fieldMapNotEmptyFlag = method.getFieldMap().size() > 0; + sb.append(indent + "inline void invoke(AMQP_ServerOperations& target, u_int16_t channel)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "target.get" + thisClass.getName() + "Handler()->" + + parseForReservedWords(Utils.firstLower(method.getName()), + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body.invoke()") + "(channel"); if (fieldMapNotEmptyFlag) { - sb.append("," + cr); - sb.append(generateFieldList(method.fieldMap, version, false, false, indentSize + 4*tabSize)); - sb.append(indent + tab + tab + tab + tab); + sb.append("," + CR); + sb.append(generateFieldList(method.getFieldMap(), version, false, false, indentSize + 4 * tabSize)); + sb.append(indent + tab + tab + tab + tab); } - sb.append(");" + cr); - sb.append(indent + "}" + cr); + sb.append(");" + CR); + sb.append(indent + "}" + CR); } } } - return sb.toString(); + return sb.toString(); } - + // Methods for generation of code snippets for amqp_methods.h/cpp files - + protected String generateMethodBodyIncludeList(AmqpModel model, int indentSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - - for (String thisClassName : model.classMap.keySet()) + + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "#include \"" + thisClass.name + Utils.firstUpper(method.name) + "Body.h\"" + cr); + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + sb.append(indent + "#include \"" + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body.h\"" + CR); } } - - return sb.toString(); + + return sb.toString(); } - + protected String generateMethodBodyInstances(AmqpModel model, int indentSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - - for (String thisClassName : model.classMap.keySet()) + + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "const " + thisClass.name + Utils.firstUpper(method.name) + "Body " + - Utils.firstLower(thisClass.name) + "_" + method.name + ";" + cr); + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + sb.append(indent + "const " + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body " + + Utils.firstLower(thisClass.getName()) + "_" + method.getName() + ";" + CR); } } - - return sb.toString(); + + return sb.toString(); } - + protected String generateMethodBodyMapEntry(AmqpModel model, int indentSize) - throws AmqpTypeMappingException { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - - for (AmqpVersion version : globalVersionSet) + + for (AmqpVersion version : getVersionSet()) { - for (String thisClassName : model.classMap.keySet()) + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String namespace = method.isVersionConsistent(globalVersionSet) ? "" : version.namespace() + "::"; + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + String namespace = method.isVersionConsistent(getVersionSet()) ? "" : version.namespace() + "::"; try { - int classOrdinal = thisClass.indexMap.getOrdinal(version); - int methodOrdinal = method.indexMap.getOrdinal(version); - String methodModyClassName = namespace + thisClass.name + Utils.firstUpper(method.name) + "Body"; + int classOrdinal = thisClass.getIndexMap().getOrdinal(version); + int methodOrdinal = method.getIndexMap().getOrdinal(version); + String methodModyClassName = namespace + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body"; sb.append(indent + "insert(std::make_pair(createMapKey(" + classOrdinal + ", " + - methodOrdinal + ", " + version.getMajor() + ", " + version.getMinor() + - "), &createMethodBodyFn<" + methodModyClassName + ">));" + cr); + methodOrdinal + ", " + version.getMajor() + ", " + version.getMinor() + + "), &createMethodBodyFn<" + methodModyClassName + ">));" + CR); } - catch (AmqpTypeMappingException e) {} // ignore + catch (AmqpTypeMappingException e) + { + } // ignore } } } - - return sb.toString(); + + return sb.toString(); } - - + // Helper functions - - private String generateVersionCheck(AmqpVersion version) - { - return "version.equals(" + version.getMajor() + ", " + version.getMinor() + ")"; - } - - private String generateVersionCheck(AmqpVersionSet versionSet) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - for (AmqpVersion v : versionSet) - { - if (!v.equals(versionSet.first())) - sb.append(" || "); - if (versionSet.size() > 1) - sb.append("("); - sb.append("version.equals(" + v.getMajor() + ", " + v.getMinor() + ")"); - if (versionSet.size() > 1) - sb.append(")"); - } - return sb.toString(); - } - - private String parseForReservedWords(String name, String context) - { - for (String cppReservedWord : cppReservedWords) - if (name.compareTo(cppReservedWord) == 0) - { + + private String generateVersionCheck(AmqpVersion version) + { + return "version.equals(" + version.getMajor() + ", " + version.getMinor() + ")"; + } + + private String generateVersionCheck(AmqpVersionSet versionSet) + { + StringBuffer sb = new StringBuffer(); + for (AmqpVersion v : versionSet) + { + if (!v.equals(versionSet.first())) + { + sb.append(" || "); + } + if (versionSet.size() > 1) + { + sb.append("("); + } + sb.append("version.equals(" + v.getMajor() + ", " + v.getMinor() + ")"); + if (versionSet.size() > 1) + { + sb.append(")"); + } + } + return sb.toString(); + } + + private String parseForReservedWords(String name, String context) + { + for (String cppReservedWord : cppReservedWords) + { + if (name.compareTo(cppReservedWord) == 0) + { if (!quietFlag) { System.out.println("WARNING: " + (context == null ? "" : context + ": ") + - "Found XML method \"" + name + "\", which is a C++ reserved word. " + - "Changing generated name to \"" + name + "_\"."); + "Found XML method \"" + name + "\", which is a C++ reserved word. " + + "Changing generated name to \"" + name + "_\"."); } - return name + "_"; - } - - for (String cppCommonDefine : cppCommonDefines) + return name + "_"; + } + } + + for (String cppCommonDefine : cppCommonDefines) + { if (name.compareTo(cppCommonDefine) == 0) { if (!quietFlag) { System.out.println("WARNING: " + (context == null ? "" : context + ": ") + - "Found XML method \"" + name + "\", which may clash with commonly used defines within C++. " + - "Changing generated name to \"" + name + "_\"."); + "Found XML method \"" + name + "\", which may clash with commonly used defines within C++. " + + "Changing generated name to \"" + name + "_\"."); } return name + "_"; } - - return name; - } - - private String setRef(String codeType) - { - if (codeType.compareTo("string") == 0 || - codeType.compareTo("FieldTable") == 0) - return "const " + codeType + "&"; - return codeType; - } - - 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(); - } + } + + return name; + } + + private String setRef(String codeType) + { + if (codeType.compareTo("string") == 0 || + codeType.compareTo("FieldTable") == 0) + { + return "const " + codeType + "&"; + } + return codeType; + } + + 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(); + } + + public static Factory<CppGenerator> _factoryInstance = new Factory<CppGenerator>() + { + + public CppGenerator newInstance() + { + return new CppGenerator(); + } + }; + + public static Factory<CppGenerator> getFactory() + { + return _factoryInstance; + } + + void processModelTemplate(NamedTemplate template, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + public String getNativeType(String type) + { + throw new UnsupportedOperationException(); + } + + public String getEncodingType(String type) + { + throw new UnsupportedOperationException(); + } + } diff --git a/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java b/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java index bd49315241..9fc81dd428 100644 --- a/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java @@ -22,319 +22,361 @@ 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. + 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 String getNativeType(String type) + { + throw new UnsupportedOperationException(); + } + + public String getEncodingType(String type) + { + throw new UnsupportedOperationException(); + } + + public DotnetGenerator() + { + super(); + // 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 + } + + void processModelTemplate(NamedTemplate template, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected String prepareFilename(String filenameTemplate, + AmqpClass thisClass, AmqpMethod method, AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(filenameTemplate); + if (thisClass != null) + { + replaceToken(sb, "${CLASS}", thisClass.getName()); + } + if (method != null) + { + replaceToken(sb, "${METHOD}", method.getName()); + } + if (field != null) + { + replaceToken(sb, "${FIELD}", field.getName()); + } + return sb.toString(); + } + + @Override + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, + int listMarkerEndIndex, AmqpModel model, AmqpVersion version) + 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 - { + } + + 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 + 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... + // 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 = 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. + } + + @Override + protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, + int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version) + { + 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) + } + + else // Oops! { - throw new AmqpTypeMappingException("Domain type \"" + domainName + - "\" not found in Java typemap."); + 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 processModelTemplate(NamedTemplate template) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + processTemplate(template, null, null, null, null); + } + + @Override + protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + processTemplate(template, thisClass, null, null, null); + } + + @Override + protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + processTemplate(template, thisClass, method, null, null); + } + + @Override + protected void processTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version); + try + { + processAllLists(sb, thisClass, method, null); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + template.getName() + ": " + e.getMessage()); + } + try + { + processAllTokens(sb, thisClass, method, field, null); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + template.getName() + ": " + e.getMessage()); + } + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + 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 getGeneratedType(String domainName, AmqpVersion version) + throws AmqpTypeMappingException + { + String domainType = 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(); - } + 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(); + } + + + public static Factory<DotnetGenerator> _factoryInstance = new Factory<DotnetGenerator>() + { + + public DotnetGenerator newInstance() + { + return new DotnetGenerator(); + } + }; + + public static Factory<DotnetGenerator> getFactory() + { + return _factoryInstance; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/GenerateMethod.java b/gentools/src/org/apache/qpid/gentools/GenerateMethod.java new file mode 100644 index 0000000000..cdbaeb8658 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/GenerateMethod.java @@ -0,0 +1,27 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+
+public interface GenerateMethod
+{
+ String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize);
+}
diff --git a/gentools/src/org/apache/qpid/gentools/Generator.java b/gentools/src/org/apache/qpid/gentools/Generator.java index e7ccd64fbe..4b04bacd81 100644 --- a/gentools/src/org/apache/qpid/gentools/Generator.java +++ b/gentools/src/org/apache/qpid/gentools/Generator.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -20,410 +20,834 @@ */ package org.apache.qpid.gentools; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.w3c.dom.Node; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; +import java.io.FilenameFilter; import java.io.IOException; import java.io.LineNumberReader; -import java.lang.reflect.InvocationTargetException; +import java.io.StringWriter; import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; public abstract class Generator implements LanguageConverter { - protected static String cr = Utils.lineSeparator; - protected static enum EnumConstOutputTypes { OUTPUT_STRING, OUTPUT_INTEGER, OUTPUT_DOUBLE; }; - - // This string is reproduced in every generated file as a comment - // TODO: Tie the version info into the build system. - protected static final String generatorInfo = "Qpid Gentools v.0.1"; - protected static final int templateFileNameIndex = 0; - protected static final int templateStringIndex = 1; - - protected ArrayList<String[]> modelTemplateList; - protected ArrayList<String[]> classTemplateList; - protected ArrayList<String[]> methodTemplateList; - protected ArrayList<String[]> fieldTemplateList; - protected String genDir; - - protected AmqpVersionSet globalVersionSet; - protected AmqpDomainMap globalDomainMap; - protected AmqpConstantSet globalConstantSet; - protected AmqpModel model; - - protected int generatedFileCounter; - - public Generator(AmqpVersionSet versionList) - { - this.globalVersionSet = versionList; - modelTemplateList = new ArrayList<String[]>(); - classTemplateList = new ArrayList<String[]>(); - methodTemplateList = new ArrayList<String[]>(); - fieldTemplateList = new ArrayList<String[]>(); - generatedFileCounter = 0; - } - - public int getNumberGeneratedFiles() - { - return generatedFileCounter; - } - - public void setDomainMap(AmqpDomainMap domainMap) - { - this.globalDomainMap = domainMap; - } - - public AmqpDomainMap getDomainMap() - { - return globalDomainMap; - } - - public void setConstantSet(AmqpConstantSet constantSet) - { - this.globalConstantSet = constantSet; - } - + protected static String CR = Utils.LINE_SEPARATOR; + + + private static final Map<String, Integer> FIXED_SIZE_TYPES = new HashMap<String, Integer>(); + + static + { + FIXED_SIZE_TYPES.put("bit", 1); + FIXED_SIZE_TYPES.put("bitfield", 1); + FIXED_SIZE_TYPES.put("long", 4); + FIXED_SIZE_TYPES.put("longlong", 8); + FIXED_SIZE_TYPES.put("octet", 1); + FIXED_SIZE_TYPES.put("short", 2); + FIXED_SIZE_TYPES.put("timestamp", 8); + + } + + private String _templateDirectory; + private String _outputDirectory; + + public AmqpDomainMap getDomainMap() + { + return _domainMap; + } + public AmqpConstantSet getConstantSet() { - return globalConstantSet; - } - - public void setModel(AmqpModel model) - { - this.model = model; - } - - public AmqpModel getModel() - { - return model; - } - - public void initializeTemplates(File[] modelTemplateFiles, File[] classTemplatesFiles, - File[] methodTemplatesFiles, File[] fieldTemplatesFiles) - throws FileNotFoundException, IOException - { - if (modelTemplateFiles.length > 0) - { - System.out.println("Model template file(s):"); - for (File mtf : modelTemplateFiles) - { - System.out.println(" " + mtf.getAbsolutePath()); - String template[] = {mtf.getName(), loadTemplate(mtf)}; - modelTemplateList.add(template); - } - } - if (classTemplatesFiles.length > 0) - { - System.out.println("Class template file(s):"); - //for (int c=0; c<classTemplatesFiles.length; c++) - for (File ctf : classTemplatesFiles) - { - System.out.println(" " + ctf.getAbsolutePath()); - String template[] = {ctf.getName(), loadTemplate(ctf)}; - classTemplateList.add(template); - } - } - if (methodTemplatesFiles.length > 0) - { - System.out.println("Method template file(s):"); - for (File mtf : methodTemplatesFiles) - { - System.out.println(" " + mtf.getAbsolutePath()); - String template[] = {mtf.getName(), loadTemplate(mtf)}; - methodTemplateList.add(template); - } - } - if (fieldTemplatesFiles.length > 0) - { - System.out.println("Field template file(s):"); - for (File ftf : fieldTemplatesFiles) - { - System.out.println(" " + ftf.getAbsolutePath()); - String template[] = {ftf.getName(), loadTemplate(ftf)}; - fieldTemplateList.add(template); - } - } - } - - abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, - AmqpField field); - - abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, - AmqpField field, AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException; - - abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpModel model) - throws AmqpTemplateException, AmqpTypeMappingException; - - abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpClass thisClass) - throws AmqpTemplateException, AmqpTypeMappingException; - - abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap, AmqpVersion version) - throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, - InvocationTargetException; - - abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) - throws AmqpTemplateException, AmqpTypeMappingException; - - public void generate(File genDir) - throws TargetDirectoryException, IOException, AmqpTypeMappingException, - AmqpTemplateException, IllegalAccessException, InvocationTargetException - { - prepareTargetDirectory(genDir, true); - System.out.println("Generation directory: " + genDir.getAbsolutePath()); - this.genDir = genDir.getAbsolutePath(); - - // Use all model-level templates - for (String[] mt : modelTemplateList) - { - processTemplateA(mt); - } - - // Cycle through classes - for (String className : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(className); - // Use all class-level templates - for (String[] ct : classTemplateList) - { - processTemplateB(ct, thisClass); - } + return _constantSet; + } + + public AmqpModel getModel() + { + return _model; + } + + abstract public String getNativeType(String type); + + abstract public String getEncodingType(String type); + + + + protected static enum EnumConstOutputTypes + { + OUTPUT_STRING, + OUTPUT_INTEGER, + OUTPUT_DOUBLE; + } + + ; + + public static enum TemplateType + { + model("model"), + clazz("class"), + method("method"), + field("field"); + + private final String _name; + + private TemplateType(String name) + { + _name = name; + } + + public String getName() + { + return _name; + } + } + + ; + + + public static interface Factory<X extends Generator> + { + public X newInstance(); + } + + + protected static final class NamedTemplate + { + private final String _name; + private final String _template; + private final File _file; + + + public NamedTemplate(String relativePath, File templateFile) + { + _file = templateFile; + _name = relativePath + Utils.FILE_SEPARATOR + templateFile.getName(); + + _template = loadTemplate(templateFile); + } + + + public String getName() + { + return _name; + } + + public String getTemplate() + { + return _template; + } + + + public File getFile() + { + return _file; + } + + } + + + private static final String VELOCITY_TEMPLATE_SUFFIX = ".vm"; + private static final String STANDARD_TEMPLATE_SUFFIX = ".tmpl"; + private static FilenameFilter _tmplFileFilter = new FilenameFilter() + { + + public boolean accept(File dir, String name) + { + return name.endsWith(STANDARD_TEMPLATE_SUFFIX) || name.endsWith(VELOCITY_TEMPLATE_SUFFIX); + } + }; + + + // This string is reproduced in every generated file as a comment + // TODO: Tie the version info into the build system. + protected static final String GENERATOR_INFO = "Qpid Gentools v.0.1"; + + + private final Map<TemplateType, Collection<NamedTemplate>> _templates = + new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class); + + private final Map<TemplateType, Collection<NamedTemplate>> _versionSpecificTemplates = + new EnumMap<TemplateType, Collection<NamedTemplate>>(TemplateType.class); - // Cycle through all methods - for (String methodName : thisClass.methodMap.keySet()) + + private final AmqpVersionSet _versionSet; + + private final AmqpDomainMap _domainMap; + private final Map<AmqpVersion, AmqpDomainMap> _versionToDomainMapMap = new HashMap<AmqpVersion, AmqpDomainMap>(); + + private final AmqpConstantSet _constantSet; + private final Map<AmqpVersion, AmqpConstantSet> _versionToConstantSetMap = new HashMap<AmqpVersion, AmqpConstantSet>(); + + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + private final AmqpModel _model; + private final Map<AmqpVersion, AmqpModel> _versionToModelMap = new HashMap<AmqpVersion, AmqpModel>(); + + protected int generatedFileCounter; + + public Generator() + { + _versionSet = new AmqpVersionSet(); + _model = new AmqpModel(this); + _constantSet = new AmqpConstantSet(this); + _domainMap = new AmqpDomainMap(this); + + generatedFileCounter = 0; + } + +// public final AmqpVersionSet getVersionSet() +// { +// return _versionSet; +// } + + + public void addVersion(AmqpVersion version) + { + _versionSet.add(version); + if (!_versionToModelMap.containsKey(version)) + { + _versionToModelMap.put(version, new AmqpModel(this)); + } + if (!_versionToDomainMapMap.containsKey(version)) + { + _versionToDomainMapMap.put(version, new AmqpDomainMap(this)); + } + if (!_versionToConstantSetMap.containsKey(version)) + { + _versionToConstantSetMap.put(version, new AmqpConstantSet(this)); + } + } + + public int getNumberGeneratedFiles() + { + return generatedFileCounter; + } + +// public AmqpDomainMap getDomainMap() +// { +// return _domainMap; +// } +// +// public AmqpConstantSet getConstantSet() +// { +// return _constantSet; +// } +// +// +// public AmqpModel getModel() +// { +// return _model; +// } + + public void initializeTemplates() throws IOException + { + + for (TemplateType type : EnumSet.allOf(TemplateType.class)) + { + ArrayList<NamedTemplate> typeTemplates = new ArrayList<NamedTemplate>(); + _templates.put(type, typeTemplates); + ArrayList<NamedTemplate> versionSpecificTypeTemplates = new ArrayList<NamedTemplate>(); + _versionSpecificTemplates.put(type, versionSpecificTypeTemplates); + + File templateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName()); + File versionTemplateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName() + Utils.FILE_SEPARATOR + "version"); + + System.out.println("Looking for template files in directory: " + templateDirectory.getAbsoluteFile()); + + File[] templateFiles = templateDirectory.listFiles(_tmplFileFilter); + + File[] versionTemplateFiles = new File[0]; + + System.out.println("Looking for vesrion specific template files in directory: " + versionTemplateDirectory.getAbsoluteFile()); + + if (versionTemplateDirectory.exists()) + { + versionTemplateFiles = versionTemplateDirectory.listFiles(_tmplFileFilter); + } + + if(templateFiles != null) { - AmqpMethod method = thisClass.methodMap.get(methodName); - // Use all method-level templates - for (String[] mt : methodTemplateList) - { - processTemplateC(mt, thisClass, method); - } - - // Cycle through all fields - for (String fieldName : method.fieldMap.keySet()) - { - AmqpField field = method.fieldMap.get(fieldName); - // Use all field-level templates - for (String[] ft : fieldTemplateList) - { - processTemplateD(ft, thisClass, method, field); - } - } + for (File templateFile : templateFiles) + { + System.out.println(type.getName() + " template file(s):"); + System.out.println(" " + templateFile.getCanonicalPath()); + typeTemplates.add(new NamedTemplate(type.getName(), templateFile)); + } } - } - } - - protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd) - throws AmqpTypeMappingException - { - int lend = sb.indexOf(Utils.lineSeparator, tokStart) + 1; // Include cr at end of line - String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr - sb.delete(tokStart, lend); - - for (AmqpVersion v : globalVersionSet) - { - // Insert copy of target line - StringBuffer isb = new StringBuffer(tline); - if (isb.indexOf("${protocol-version-list-entry}") >= 0) + + if(versionTemplateFiles != null) { - String versionListEntry = " { ${major}, ${minor} }" + - (v.equals(globalVersionSet.last()) ? "" : ","); - replaceToken(isb, "${protocol-version-list-entry}", String.valueOf(versionListEntry)); + for (File versionTemplateFile : versionTemplateFiles) + { + System.out.println(type.getName() + " template file(s):"); + System.out.println(" " + versionTemplateFile.getCanonicalPath()); + versionSpecificTypeTemplates.add(new NamedTemplate(type.getName() + Utils.FILE_SEPARATOR + "version", versionTemplateFile)); + } } - if (isb.indexOf("${major}") >= 0) - replaceToken(isb, "${major}", String.valueOf(v.getMajor())); - if (isb.indexOf("${minor}") >= 0) - replaceToken(isb, "${minor}", String.valueOf(v.getMinor())); - sb.insert(tokStart, isb.toString()); - tokStart += isb.length(); - } - } - - // Model-level template processing - abstract protected void processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Class-level template processing - abstract protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Method-level template processing - abstract protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Field-level template processing - abstract protected void processTemplateD(String[] template, AmqpClass thisClass, - AmqpMethod method, AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Helper functions common to all generators - - protected static void prepareTargetDirectory(File dir, boolean createFlag) - throws TargetDirectoryException - { - if (dir.exists()) - { - if (!dir.isDirectory()) - throw new TargetDirectoryException("\"" + dir.getAbsolutePath() + - "\" exists, but is not a directory."); - } - else if (createFlag) // Create dir - { - if(!dir.mkdirs()) - throw new TargetDirectoryException("Unable to create directory \"" + - dir.getAbsolutePath() + "\"."); - } - else - throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() + - "\" not found."); - - } - - protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - int lstart = sb.indexOf("%{"); - while (lstart != -1) - { - int lend = sb.indexOf("}", lstart + 2); - if (lend > 0) - { - String listToken = sb.substring(lstart + 2, lend); - if (listToken.compareTo("VLIST") == 0) - { - processVersionList(sb, lstart, lend + 1); - } - else if (listToken.compareTo("CLIST") == 0) - { - processClassList(sb, lstart, lend + 1, model); - } - else if (listToken.compareTo("MLIST") == 0) - { - processMethodList(sb, lstart, lend + 1, thisClass); - } - else if (listToken.compareTo("FLIST") == 0) - { - // Pass the FieldMap from either a class or a method. - // If this is called from a class-level template, we assume that the - // class field list is required. In this case, method will be null. - processFieldList(sb, lstart, lend + 1, - (method == null ? thisClass.fieldMap : method.fieldMap), - version); - } + + } + } + + public String getTemplateDirectory() + { + return _templateDirectory; + } + + + public void setTemplateDirectory(String templateDirectory) + { + _templateDirectory = templateDirectory; + } + + + public void setOutputDirectory(String outputDirectory) + { + _outputDirectory = outputDirectory; + } + + public void generate() + { + prepareTargetDirectory(new File(_outputDirectory), true); + System.out.println("Generation directory: " + _outputDirectory); + + + processModelTemplates(_templates); + + for (AmqpClass amqpClass : _model.getClassMap().values()) + { + processClassTemplates(_templates, amqpClass); + + for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values()) + { + processMethodTemplates(_templates, amqpClass, amqpMethod); + + for (AmqpField amqpField : amqpMethod.getFieldMap().values()) + { + processFieldTemplates(_templates, amqpClass, amqpMethod, amqpField, null); + } + } + } + + + for (AmqpVersion version : _versionSet) + { + AmqpModel model = _versionToModelMap.get(version); + processModelTemplates(_versionSpecificTemplates, version); + + for (AmqpClass amqpClass : model.getClassMap().values()) + { + processClassTemplates(_versionSpecificTemplates, amqpClass, version); + + for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values()) + { + processMethodTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, version); + + for (AmqpField amqpField : amqpMethod.getFieldMap().values()) + { + processFieldTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, amqpField, version); + } + } + } + + } + } + + private void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version) + { + for (NamedTemplate template : templates.get(TemplateType.method)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,version,amqpClass,amqpMethod,null); + } + else + { + processMethodTemplate(template, amqpClass, amqpMethod); + } + } + + } + + private void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpVersion version) + { + for (NamedTemplate template : templates.get(TemplateType.clazz)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,version,amqpClass,null,null); + } + else + { + processClassTemplate(template, amqpClass); + } + } + + } + + + private void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpVersion version) + { + for (NamedTemplate template : templates.get(TemplateType.model)) + { + if (isVelocityTemplate(template)) + { + processModelVelocityTemplate(template, version); + } + else + { + processModelTemplate(template, version); + } + } + } + + abstract void processModelTemplate(NamedTemplate template, AmqpVersion version); + + + protected void processModelTemplates(Map<TemplateType, Collection<NamedTemplate>> templates) + { + for (NamedTemplate template : templates.get(TemplateType.model)) + { + if (isVelocityTemplate(template)) + { + processModelVelocityTemplate(template, null); + } + else + { + processModelTemplate(template); + } + } + } + + private boolean isVelocityTemplate(NamedTemplate template) + { + return template.getName().endsWith(VELOCITY_TEMPLATE_SUFFIX); + } + + private void processModelVelocityTemplate(NamedTemplate template, AmqpVersion version) + { + processVelocityTemplate(template,version,null,null,null); + } + + private void processVelocityTemplate(NamedTemplate template, AmqpVersion version, + AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField) + { + + VelocityContext context = new VelocityContext(); + + AmqpModel model = _model; + if(version != null) + { + model = _versionToModelMap.get(version); + } + context.put("model", model); + context.put("generator", GENERATOR_INFO); + + if (version != null) + { + context.put("version", version); + } + if(amqpClass != null) + { + context.put("amqpClass", amqpClass); + } + + if(amqpClass != null) + { + context.put("amqpMethod", amqpMethod); + } + + + StringWriter sw = new StringWriter(); + + + try + { + Template velocityTemplate = Velocity.getTemplate(template.getName()); + velocityTemplate.merge(context, sw); + String filename = String.valueOf(context.get("filename")); + FileWriter outputFileWriter = new FileWriter(getOutputDirectory() + Utils.FILE_SEPARATOR + filename); + outputFileWriter.append(sw.toString()); + outputFileWriter.close(); + + } + catch (Exception e) + { + e.printStackTrace(); + } + + + } + + + protected void processClassTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass) + { + for (NamedTemplate template : templates.get(TemplateType.clazz)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,null,amqpClass,null,null); + } + else + { + processClassTemplate(template, amqpClass); + } + } + } + + protected void processMethodTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod) + { + for (NamedTemplate template : templates.get(TemplateType.method)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,null,amqpClass,amqpMethod,null); + } + else + { + processMethodTemplate(template, amqpClass, amqpMethod); + } + } + } + + + protected void processFieldTemplates(Map<TemplateType, Collection<NamedTemplate>> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion amqpVersion) + { + for (NamedTemplate template : templates.get(TemplateType.field)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,amqpVersion,amqpClass,amqpMethod,amqpField); + } + else + { + processTemplate(template, amqpClass, amqpMethod, amqpField, amqpVersion); + } + } + } + + + protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd) + { + int lend = sb.indexOf(Utils.LINE_SEPARATOR, tokStart) + 1; // Include cr at end of line + String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr + sb.delete(tokStart, lend); + + for (AmqpVersion v : _versionSet) + { + // Insert copy of target line + StringBuffer isb = new StringBuffer(tline); + if (isb.indexOf("${protocol-version-list-entry}") >= 0) + { + String versionListEntry = " { ${major}, ${minor} }" + + (v.equals(_versionSet.last()) ? "" : ","); + replaceToken(isb, "${protocol-version-list-entry}", String.valueOf(versionListEntry)); + } + if (isb.indexOf("${major}") >= 0) + { + replaceToken(isb, "${major}", String.valueOf(v.getMajor())); + } + if (isb.indexOf("${minor}") >= 0) + { + replaceToken(isb, "${minor}", String.valueOf(v.getMinor())); + } + sb.insert(tokStart, isb.toString()); + tokStart += isb.length(); + } + } + + // Helper functions common to all generators + + protected static void prepareTargetDirectory(File dir, boolean createFlag) + { + if (dir.exists()) + { + if (!dir.isDirectory()) + { + throw new TargetDirectoryException("\"" + dir.getAbsolutePath() + + "\" exists, but is not a directory."); + } + } + else if (createFlag) // Create dir + { + if (!dir.mkdirs()) + { + throw new TargetDirectoryException("Unable to create directory \"" + + dir.getAbsolutePath() + "\"."); + } + } + else + { + throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() + + "\" not found."); + } + + } + + protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version) + { + AmqpModel model = (version == null) ? _model : _versionToModelMap.get(version); + + + int lstart = sb.indexOf("%{"); + while (lstart != -1) + { + int lend = sb.indexOf("}", lstart + 2); + if (lend > 0) + { + String listToken = sb.substring(lstart + 2, lend); + if (listToken.compareTo("VLIST") == 0) + { + processVersionList(sb, lstart, lend + 1); + } + else if (listToken.compareTo("CLIST") == 0) + { + processClassList(sb, lstart, lend + 1, model, version); + } + else if (listToken.compareTo("MLIST") == 0) + { + processMethodList(sb, lstart, lend + 1, thisClass); + } + else if (listToken.compareTo("FLIST") == 0) + { + // Pass the FieldMap from either a class or a method. + // If this is called from a class-level template, we assume that the + // class field list is required. In this case, method will be null. + processFieldList(sb, lstart, lend + 1, + (method == null ? thisClass.getFieldMap() : method.getFieldMap()), + version); + } else if (listToken.compareTo("TLIST") == 0) { - processConstantList(sb, lstart, lend + 1, globalConstantSet); + processConstantList(sb, lstart, lend + 1, _constantSet); } - else - { - throw new AmqpTemplateException("Unknown list token \"%{" + listToken + - "}\" found in template at index " + lstart + "."); - } - } - lstart = sb.indexOf("%{", lstart + 1); - } - } - - protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - int lstart = sb.indexOf("${"); - while (lstart != -1) - { - int lend = sb.indexOf("}", lstart + 2); - if (lend > 0) - { - String token = sb.substring(lstart, lend + 1); - replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version)); - } - lstart = sb.indexOf("${", lstart); - } - } - - protected static void writeTargetFile(StringBuffer sb, File f) - throws IOException - { - FileWriter fw = new FileWriter(f); - fw.write(sb.toString().toCharArray()); - fw.flush(); - fw.close(); - } - - protected static String getTemplateFileName(StringBuffer sb) - throws AmqpTemplateException - { - if (sb.charAt(0) != '&') - throw new AmqpTemplateException("No filename marker &{filename} found at start of template."); - int cr = sb.indexOf(Utils.lineSeparator); - if (cr < 0) - throw new AmqpTemplateException("Bad template structure - unable to find first line."); - String fileName = sb.substring(2, cr-1); - sb.delete(0, cr + 1); - return fileName; - } - - protected static void replaceToken(StringBuffer sb, String token, String replacement) - { - replaceToken(sb, 0, token, replacement); - } - - protected static void replaceToken(StringBuffer sb, int index, String token, String replacement) - { - if (replacement != null) - { - int start = sb.indexOf(token, index); - int len = token.length(); - // Find first letter in token and determine if it is capitalized - char firstTokenLetter = getFirstLetter(token); - if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter)) - sb.replace(start, start+len, Utils.firstUpper(replacement)); - else - sb.replace(start, start+len, replacement); - } - } - - private static char getFirstLetter(String str) - { - int len = str.length(); - int index = 0; - char tokChar = str.charAt(index); - while (!Character.isLetter(tokChar) && index<len-1) - tokChar = str.charAt(++index); - if (Character.isLetter(tokChar)) - return tokChar; - return 0; - } - - private static String loadTemplate(File f) - throws FileNotFoundException, IOException - { - StringBuffer sb = new StringBuffer(); - FileReader fr = new FileReader(f); - LineNumberReader lnr = new LineNumberReader(fr); - String line = lnr.readLine(); - while (line != null) - { - // Strip lines starting with '#' in template - treat these lines as template comments -// if (line.length() > 0 && line.charAt(0) != '#') // Bad idea - '#' used in C/C++ files (#include)! - if (line.length() > 0) - sb.append(line + Utils.lineSeparator); - else - sb.append(Utils.lineSeparator); - line = lnr.readLine(); - } - lnr.close(); - fr.close(); - return sb.toString(); - } + else + { + throw new AmqpTemplateException("Unknown list token \"%{" + listToken + + "}\" found in template at index " + lstart + "."); + } + } + lstart = sb.indexOf("%{", lstart + 1); + } + } + + protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) + { + int lstart = sb.indexOf("${"); + while (lstart != -1) + { + int lend = sb.indexOf("}", lstart + 2); + if (lend > 0) + { + String token = sb.substring(lstart, lend + 1); + replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version)); + } + lstart = sb.indexOf("${", lstart); + } + } + + protected static void writeTargetFile(StringBuffer sb, File f) + { + try + { + f.getParentFile().mkdirs(); + FileWriter fw = new FileWriter(f); + fw.write(sb.toString().toCharArray()); + fw.flush(); + fw.close(); + } + catch (IOException e) + { + throw new AmqpTemplateException(e.getMessage()); + } + } + + + protected static String getTemplateFileName(StringBuffer sb) + { + if (sb.charAt(0) != '&') + { + throw new AmqpTemplateException("No filename marker &{filename} found at start of template."); + } + int cr = sb.indexOf(Utils.LINE_SEPARATOR); + if (cr < 0) + { + throw new AmqpTemplateException("Bad template structure - unable to find first line."); + } + String fileName = sb.substring(2, cr - 1); + sb.delete(0, cr + 1); + return fileName; + } + + protected static void replaceToken(StringBuffer sb, String token, String replacement) + { + replaceToken(sb, 0, token, replacement); + } + + protected static void replaceToken(StringBuffer sb, int index, String token, String replacement) + { + if (replacement != null) + { + int start = sb.indexOf(token, index); + if (start != -1) + { + int len = token.length(); + // Find first letter in token and determine if it is capitalized + char firstTokenLetter = getFirstLetter(token); + if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter)) + { + sb.replace(start, start + len, Utils.firstUpper(replacement)); + } + else + { + sb.replace(start, start + len, replacement); + } + } + } + } + + private static char getFirstLetter(String str) + { + int len = str.length(); + int index = 0; + char tokChar = str.charAt(index); + while (!Character.isLetter(tokChar) && index < len - 1) + { + tokChar = str.charAt(++index); + } + if (Character.isLetter(tokChar)) + { + return tokChar; + } + return 0; + } + + private static String loadTemplate(File f) + { + try + { + StringBuffer sb = new StringBuffer(); + FileReader fr = new FileReader(f); + LineNumberReader lnr = new LineNumberReader(fr); + String line = lnr.readLine(); + while (line != null) + { + + sb.append(line); + sb.append(Utils.LINE_SEPARATOR); + + line = lnr.readLine(); + } + lnr.close(); + fr.close(); + return sb.toString(); + } + catch (FileNotFoundException e) + { + throw new AmqpTemplateException("File not found: " + e.getMessage()); + } + catch (IOException e) + { + throw new AmqpTemplateException("IOException: " + e.getMessage()); + } + } + + public String getDomainType(String domainName, AmqpVersion version) + { + if (version == null) + { + version = _versionSet.first(); + } + return getDomainMap().getDomainType(domainName, version); + } + + + public void addFromNode(Node amqpNode, AmqpVersion version) + { + // 1c. Extract domains + getConstantSet().addFromNode(amqpNode, 0, version); + _versionToConstantSetMap.get(version).addFromNode(amqpNode, 0, version); + + // 1d. Extract domains + getDomainMap().addFromNode(amqpNode, 0, version); + _versionToDomainMapMap.get(version).addFromNode(amqpNode, 0, version); + + // 1e. Extract class/method/field heirarchy + getModel().addFromNode(amqpNode, 0, version); + _versionToModelMap.get(version).addFromNode(amqpNode, 0, version); + } + + + public String getOutputDirectory() + { + return _outputDirectory; + } + + public String prepareConstantName(String constantName) + { + return prepareDomainName(constantName); + } + + + public boolean isFixedSizeType(String type) + { + return FIXED_SIZE_TYPES.containsKey(type); + } + + + public int getTypeSize(String type) + { + return FIXED_SIZE_TYPES.get(type); + } + + + + // Model-level template processing + abstract protected void processModelTemplate(NamedTemplate template); + + // Class-level template processing + abstract protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass); + + // Method-level template processing + abstract protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method); + + // Field-level template processing + abstract protected void processTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version); + + abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version); + + abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version); + + abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model, AmqpVersion version); + + abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpClass thisClass); + + + abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpFieldMap fieldMap, AmqpVersion version); + + abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpConstantSet constantSet); + + } diff --git a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java index 84d06cf204..7730fca1bd 100644 --- a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java @@ -21,664 +21,717 @@ 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.List; import java.util.TreeMap; public class JavaGenerator extends Generator { - // TODO: Move this to parent class - protected static final int FIELD_NAME = 0; - protected static final int FIELD_CODE_TYPE = 1; - - 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>(); - - // Methods used for generation of code snippets called from the field map parsers - - // Common methods - static private Method declarationGenerateMethod; - static private Method mangledDeclarationGenerateMethod; - - // Methods for MessageBody classes - static private Method mbGetGenerateMethod; - static private Method mbMangledGetGenerateMethod; - static private Method mbParamListGenerateMethod; - static private Method mbPassedParamListGenerateMethod; - static private Method mbMangledParamListGenerateMethod; - static private Method mbMangledPassedParamListGenerateMethod; - static private Method mbBodyInitGenerateMethod; - static private Method mbMangledBodyInitGenerateMethod; - static private Method mbSizeGenerateMethod; - static private Method mbBitSizeGenerateMethod; - static private Method mbEncodeGenerateMethod; - static private Method mbBitEncodeGenerateMethod; - static private Method mbDecodeGenerateMethod; - static private Method mbBitDecodeGenerateMethod; - static private Method mbToStringGenerateMethod; - static private Method mbBitToStringGenerateMethod; - - // Methods for PropertyContentHeader classes - static private Method pchClearGenerateMethod; - static private Method pchMangledClearGenerateMethod; - static private Method pchGetGenerateMethod; - static private Method pchMangledGetGenerateMethod; - static private Method pchSetGenerateMethod; - static private Method pchMangledSetGenerateMethod; - static private Method pchSizeGenerateMethod; - static private Method pchBitSizeGenerateMethod; - static private Method pchEncodeGenerateMethod; - static private Method pchBitEncodeGenerateMethod; - static private Method pchDecodeGenerateMethod; - static private Method pchBitDecodeGenerateMethod; - static private Method pchGetPropertyFlagsGenerateMethod; - static private Method pchBitGetPropertyFlagsGenerateMethod; - static private Method pchSetPropertyFlagsGenerateMethod; - static private Method pchBitSetPropertyFlagsGenerateMethod; - - static - { - // ************** - // Common methods - // ************** - - // Methods for AmqpFieldMap.parseFieldMap() - - try { declarationGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateFieldDeclaration", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mangledDeclarationGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMangledFieldDeclaration", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - - // ******************************* - // Methods for MessageBody classes - // ******************************* - - // Methods for AmqpFieldMap.parseFieldMap() - - try { mbGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbGetMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledGetMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbParamList", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - - try { mbPassedParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbPassedParamList", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledParamList", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledPassedParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledPassedParamList", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBodyInitGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBodyInit", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledBodyInitGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledBodyInit", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - // Methods for AmqpFieldMap.parseFieldMapOrdinally() - - try { mbSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldSize", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitArrayFieldSize", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldEncode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitFieldEncode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldDecode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitFieldDecode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbToStringGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldToString", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitToStringGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitFieldToString", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - // ***************************************** - // Methods for PropertyContentHeader classes - // ***************************************** - - // Methods for AmqpFieldMap.parseFieldMap() - - try { pchClearGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchClearMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchMangledClearGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchMangledClearMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchSetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchSetMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchMangledSetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchMangledSetMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchGetMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchMangledGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchMangledGetMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - // Methods for AmqpFieldMap.parseFieldMapOrdinally() - - try { pchSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchFieldSize", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitArrayFieldSize", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchFieldEncode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitFieldEncode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchFieldDecode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitFieldDecode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchGetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchGetPropertyFlags", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitGetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitGetPropertyFlags", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchSetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchSetPropertyFlags", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitSetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitSetPropertyFlags", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - } - - public JavaGenerator(AmqpVersionSet versionList) - { - super(versionList); - // Load Java 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). - typeMap.put("bit", new DomainInfo( - "boolean", // Java code type - "~", // size - "EncodingUtils.writeBooleans(buffer, #)", // encode expression - "# = EncodingUtils.readBooleans(buffer)")); // decode expression - typeMap.put("content", new DomainInfo( - "Content", // Java code type - "EncodingUtils.encodedContentLength(#)", // size - "EncodingUtils.writeContentBytes(buffer, #)", // encode expression - "# = EncodingUtils.readContent(buffer)")); // decode expression - typeMap.put("long", new DomainInfo( - "long", // Java code type - "4", // size - "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression - "# = buffer.getUnsignedInt()")); // decode expression - typeMap.put("longlong", new DomainInfo( - "long", // Java code type - "8", // size - "buffer.putLong(#)", // encode expression - "# = buffer.getLong()")); // decode expression - typeMap.put("longstr", new DomainInfo( - "byte[]", // Java code type - "EncodingUtils.encodedLongstrLength(#)", // size - "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression - "# = EncodingUtils.readLongstr(buffer)")); // decode expression - typeMap.put("octet", new DomainInfo( - "short", // Java code type - "1", // size - "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression - "# = buffer.getUnsigned()")); // decode expression - typeMap.put("short", new DomainInfo( - "int", // Java code type - "2", // size - "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression - "# = buffer.getUnsignedShort()")); // decode expression - typeMap.put("shortstr", new DomainInfo( - "AMQShortString", // Java code type - "EncodingUtils.encodedShortStringLength(#)", // size - "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression - "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression - typeMap.put("table", new DomainInfo( - "FieldTable", // Java code type - "EncodingUtils.encodedFieldTableLength(#)", // size - "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression - "# = EncodingUtils.readFieldTable(buffer)")); // decode expression - typeMap.put("timestamp", new DomainInfo( - "long", // Java code type - "8", // size - "EncodingUtils.writeTimestamp(buffer, #)", // encode expression - "# = EncodingUtils.readTimestamp(buffer)")); // decode expression - } - - // === Start of methods for Interface LanguageConverter === - - public String prepareClassName(String className) - { - return camelCaseName(className, true); - } - - public String prepareMethodName(String methodName) - { - return camelCaseName(methodName, false); - } - - public String prepareDomainName(String domainName) - { - return camelCaseName(domainName, false); - } - - 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."); + // TODO: Move this to parent class + protected static final int FIELD_NAME = 0; + protected static final int FIELD_CODE_TYPE = 1; + + private class DomainInfo + { + final public String type; + final public String size; + final public String encodingType; + final public String encodeExpression; + final public String decodeExpression; + + public DomainInfo(String domain, String size, String encodingType, String encodeExpression, String decodeExpression) + { + this.type = domain; + this.size = size; + this.encodeExpression = encodeExpression; + this.decodeExpression = decodeExpression; + this.encodingType = encodingType; + } + } + + private static TreeMap<String, DomainInfo> typeMap = new TreeMap<String, DomainInfo>(); + + // Methods used for generation of code snippets called from the field map parsers + + // Common methods + private final CommandGenerateMethod declarationGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateFieldDeclaration(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + + private MangledGenerateMethod mangledDeclarationGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMangledFieldDeclaration(field, indentSize, tabSize, notLast); + } + }; + + // Methods for MessageBody classes + private CommandGenerateMethod mbGetGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbGetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); //To change body of implemented methods use File | Settings | File Templates. + } + }; + + private MangledGenerateMethod mbMangledGetGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledGetMethod(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod mbParamListGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbParamList(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod mbPassedParamListGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbPassedParamList(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod mbMangledParamListGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledParamList(field, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod mbMangledPassedParamListGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledPassedParamList(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod mbBodyInitGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbBodyInit(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod mbMangledBodyInitGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledBodyInit(field, indentSize, tabSize, notLast); + } + }; + private GenerateMethod mbSizeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldSize(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitSizeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitArrayFieldSize(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod mbEncodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldEncode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitEncodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitFieldEncode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod mbDecodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldDecode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitDecodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitFieldDecode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod mbToStringGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldToString(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitToStringGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitFieldToString(bitFieldList, ordinal, indentSize, tabSize); + } + }; + + // Methods for PropertyContentHeader classes + private CommandGenerateMethod pchClearGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generatePchClearMethod(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod pchMangledClearGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generatePchMangledClearMethod(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod pchGetGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generatePchGetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod pchMangledGetGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generatePchMangledGetMethod(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod pchSetGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generatePchSetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod pchMangledSetGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generatePchMangledSetMethod(field, indentSize, tabSize, notLast); + } + }; + private GenerateMethod pchSizeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchFieldSize(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitSizeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitArrayFieldSize(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchEncodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchFieldEncode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitEncodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitFieldEncode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchDecodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchFieldDecode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitDecodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitFieldDecode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchGetPropertyFlagsGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchGetPropertyFlags(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitGetPropertyFlagsGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitGetPropertyFlags(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchSetPropertyFlagsGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchSetPropertyFlags(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitSetPropertyFlagsGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List<String> bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitSetPropertyFlags(bitFieldList, ordinal, indentSize, tabSize); + } + }; + + + public String getNativeType(String type) + { + return typeMap.get(type).type; + } + + public String getEncodingType(String type) + { + return typeMap.get(type).encodingType; + } + + + public JavaGenerator() + { + super(); + // Load Java 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). + typeMap.put("bit", new DomainInfo( + "boolean", // Java code type + "~", // size + "Boolean", // Java code type + "EncodingUtils.writeBooleans(buffer, #)", // encode expression + "# = EncodingUtils.readBooleans(buffer)")); // decode expression + typeMap.put("bitfield", new DomainInfo( + "byte", // Java code type + "~", // size + "Bitfield", + "EncodingUtils.writeBooleans(buffer, #)", // encode expression + "# = EncodingUtils.readBooleans(buffer)")); // decode expression + + typeMap.put("content", new DomainInfo( + "Content", // Java code type + "EncodingUtils.encodedContentLength(#)", // size + "Content", // Java code type + "EncodingUtils.writeContentBytes(buffer, #)", // encode expression + "# = EncodingUtils.readContent(buffer)")); // decode expression + typeMap.put("long", new DomainInfo( + "long", // Java code type + "4", // size + "UnsignedInteger", // Java code type + "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression + "# = buffer.getUnsignedInt()")); // decode expression + typeMap.put("longlong", new DomainInfo( + "long", // Java code type + "8", // size + "Long", + "buffer.putLong(#)", // encode expression + "# = buffer.getLong()")); // decode expression + typeMap.put("longstr", new DomainInfo( + "byte[]", // Java code type + "EncodingUtils.encodedLongstrLength(#)", // size + "Bytes", + "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression + "# = EncodingUtils.readLongstr(buffer)")); // decode expression + typeMap.put("octet", new DomainInfo( + "short", // Java code type + "1", // size + "UnsignedByte", + "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression + "# = buffer.getUnsigned()")); // decode expression + typeMap.put("short", new DomainInfo( + "int", // Java code type + "2", // size + "UnsignedShort", + "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression + "# = buffer.getUnsignedShort()")); // decode expression + typeMap.put("shortstr", new DomainInfo( + "AMQShortString", // Java code type + "EncodingUtils.encodedShortStringLength(#)", // size + "AMQShortString", // Java code type + "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression + "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression + typeMap.put("table", new DomainInfo( + "FieldTable", // Java code type + "EncodingUtils.encodedFieldTableLength(#)", // size + "FieldTable", // Java code type + "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression + "# = EncodingUtils.readFieldTable(buffer)")); // decode expression + typeMap.put("timestamp", new DomainInfo( + "long", // Java code type + "8", // size + "Timestamp", + "EncodingUtils.writeTimestamp(buffer, #)", // encode expression + "# = EncodingUtils.readTimestamp(buffer)")); // decode expression + } + + // === Start of methods for Interface LanguageConverter === + + public String prepareClassName(String className) + { + return camelCaseName(className, true); + } + + public String prepareMethodName(String methodName) + { + return camelCaseName(methodName, false); + } + + public String prepareDomainName(String domainName) + { + return camelCaseName(domainName, false); + } + + + public String getGeneratedType(String domainName, AmqpVersion version) + { + String domainType = 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; - } - - - // === Abstract methods from class Generator - Java-specific implementations === - - @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 processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, method, null); - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, - AmqpMethod method, AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[1]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, - AmqpField field, String templateFileName, AmqpVersion version) - throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException - { - try { processAllLists(sb, thisClass, method, version); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, version); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); - } - } - - @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - if (token.compareTo("${GENERATOR}") == 0) - return generatorInfo; - if (token.compareTo("${CLASS}") == 0 && thisClass != null) - return thisClass.name; - if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) - return generateIndexInitializer("registerClassId", thisClass.indexMap, 8); - if (token.compareTo("${METHOD}") == 0 && method != null) - return method.name; - if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) - return generateIndexInitializer("registerMethodId", method.indexMap, 8); - if (token.compareTo("${FIELD}") == 0 && field != null) - return field.name; - - // This token is used only with class or method-level templates - if (token.compareTo("${pch_property_flags_declare}") == 0) - { - return generatePchPropertyFlagsDeclare(); - } - else if (token.compareTo("${pch_property_flags_initializer}") == 0) - { - int mapSize = method == null ? thisClass.fieldMap.size() : method.fieldMap.size(); - return generatePchPropertyFlagsInitializer(mapSize); - } - else if (token.compareTo("${pch_compact_property_flags_initializer}") == 0) - { - return generatePchCompactPropertyFlagsInitializer(thisClass, 8, 4); - } - else if (token.compareTo("${pch_compact_property_flags_check}") == 0) - { - return generatePchCompactPropertyFlagsCheck(thisClass, 8, 4); - } - - // Oops! - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - @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); - - if (token.compareTo("${reg_map_put_method}") == 0) - { - codeSnippet = generateRegistry(model, 8, 4); - } - - 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 - we don't have any cases of this (yet). - if (token.compareTo("${???}") == 0) - { - codeSnippet = token; - } - 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); - - // Field declarations - common to MethodBody and PropertyContentHeader classes - if (token.compareTo("${field_declaration}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, - mangledDeclarationGenerateMethod, 4, 4, this); - } - - // MethodBody classes - else if (token.compareTo("${mb_field_get_method}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod, - mbMangledGetGenerateMethod, 4, 4, this); - } - else if (token.compareTo("${mb_field_parameter_list}") == 0) - { - // <cringe> The code generated by this is ugly... It puts a comma on a line by itself! - // TODO: Find a more elegant solution here sometime... - codeSnippet = fieldMap.size() > 0 ? Utils.createSpaces(42) + "," + cr : ""; - // </cringe> - codeSnippet += fieldMap.parseFieldMap(mbParamListGenerateMethod, - mbMangledParamListGenerateMethod, 42, 4, this); - } - - else if (token.compareTo("${mb_field_passed_parameter_list}") == 0) - { - // <cringe> The code generated by this is ugly... It puts a comma on a line by itself! - // TODO: Find a more elegant solution here sometime... - codeSnippet = fieldMap.size() > 0 ? Utils.createSpaces(42) + "," + cr : ""; - // </cringe> - codeSnippet += fieldMap.parseFieldMap(mbPassedParamListGenerateMethod, - mbMangledPassedParamListGenerateMethod, 42, 4, this); - } - else if (token.compareTo("${mb_field_body_initialize}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(mbBodyInitGenerateMethod, - mbMangledBodyInitGenerateMethod, 8, 4, this); - } - else if (token.compareTo("${mb_field_size}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbSizeGenerateMethod, - mbBitSizeGenerateMethod, 8, 4, this); - } - else if (token.compareTo("${mb_field_encode}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbEncodeGenerateMethod, - mbBitEncodeGenerateMethod, 8, 4, this); - } - else if (token.compareTo("${mb_field_decode}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbDecodeGenerateMethod, - mbBitDecodeGenerateMethod, 8, 4, this); - } - else if (token.compareTo("${mb_field_to_string}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(mbToStringGenerateMethod, - mbBitToStringGenerateMethod, 8, 4, this); - } - - // PropertyContentHeader classes - else if (token.compareTo("${pch_field_list_size}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(pchSizeGenerateMethod, - pchBitSizeGenerateMethod, 12, 4, this); - } - else if (token.compareTo("${pch_field_list_payload}") == 0 ) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(pchEncodeGenerateMethod, - pchBitEncodeGenerateMethod, 12, 4, this); - } - else if (token.compareTo("${pch_field_list_decode}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(pchDecodeGenerateMethod, - pchBitDecodeGenerateMethod, 12, 4, this); - } - else if (token.compareTo("${pch_get_compact_property_flags}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(pchGetPropertyFlagsGenerateMethod, - pchBitGetPropertyFlagsGenerateMethod, 8, 4, this); - } - else if (token.compareTo("${pch_set_compact_property_flags}") == 0) - { - codeSnippet = fieldMap.parseFieldMapOrdinally(pchSetPropertyFlagsGenerateMethod, - pchBitSetPropertyFlagsGenerateMethod, 8, 4, this); - } - else if (token.compareTo("${pch_field_clear_methods}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(pchClearGenerateMethod, - pchMangledClearGenerateMethod, 4, 4, this); - } - else if (token.compareTo("${pch_field_get_methods}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(pchGetGenerateMethod, - pchMangledGetGenerateMethod, 4, 4, this); - } - else if (token.compareTo("${pch_field_set_methods}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(pchSetGenerateMethod, - pchMangledSetGenerateMethod, 4, 4, this); - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } + return info.type; + } + + // === Abstract methods from class Generator - Java-specific implementations === @Override - protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) - throws AmqpTemplateException, AmqpTypeMappingException + protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(filenameTemplate); + if (thisClass != null) + { + replaceToken(sb, "${CLASS}", thisClass.getName()); + } + if (method != null) + { + replaceToken(sb, "${METHOD}", method.getName()); + } + if (field != null) + { + replaceToken(sb, "${FIELD}", field.getName()); + } + if (version != null) + { + replaceToken(sb, "${MAJOR}", String.valueOf(version.getMajor())); + replaceToken(sb, "${MINOR}", String.valueOf(version.getMinor())); + } + return sb.toString(); + } + + @Override + protected void processModelTemplate(NamedTemplate template) + { + processTemplate(template, null, null, null, null); + } + + @Override + protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass) + { + processTemplate(template, thisClass, null, null, + thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null); + } + @Override + protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method) + { + processTemplate(template, thisClass, method, null, + thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null); + } + + protected void processFieldTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field) + { + processTemplate(template, thisClass, method, field, + thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null); + } + + @Override + protected void processTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version); + processTemplate(sb, thisClass, method, field, template.getName(), version); + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, + AmqpField field, String templateFileName, AmqpVersion version) + { + try + { + processAllLists(sb, thisClass, method, version); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + try + { + processAllTokens(sb, thisClass, method, field, version); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + } + + @Override + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) + { + if (token.compareTo("${GENERATOR}") == 0) + { + return GENERATOR_INFO; + } + if (token.compareTo("${CLASS}") == 0 && thisClass != null) + { + return thisClass.getName(); + } + if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) + { + return generateIndexInitializer("registerClassId", thisClass.getIndexMap(), 8); + } + if (token.compareTo("${METHOD}") == 0 && method != null) + { + return method.getName(); + } + if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) + { + return generateIndexInitializer("registerMethodId", method.getIndexMap(), 8); + } + if (token.compareTo("${FIELD}") == 0 && field != null) + { + return field.getName(); + } + + // This token is used only with class or method-level templates + if (token.compareTo("${pch_property_flags_declare}") == 0) + { + return generatePchPropertyFlagsDeclare(); + } + else if (token.compareTo("${pch_property_flags_initializer}") == 0) + { + int mapSize = method == null ? thisClass.getFieldMap().size() : method.getFieldMap().size(); + return generatePchPropertyFlagsInitializer(mapSize); + } + else if (token.compareTo("${pch_compact_property_flags_initializer}") == 0) + { + return generatePchCompactPropertyFlagsInitializer(thisClass, 8, 4); + } + else if (token.compareTo("${pch_compact_property_flags_check}") == 0) + { + return generatePchCompactPropertyFlagsCheck(thisClass, 8, 4); + } + + // Oops! + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + @Override + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model, AmqpVersion version) + { + 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); + + if (token.compareTo("${reg_map_put_method}") == 0) { + codeSnippet = generateRegistry(model, 8, 4); + } + + 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) + { String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + 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 - we don't have any cases of this (yet). + if (token.compareTo("${???}") == 0) + { + codeSnippet = token; + } + 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) + { + 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); + + // Field declarations - common to MethodBody and PropertyContentHeader classes + if (token.compareTo("${field_declaration}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, + mangledDeclarationGenerateMethod, 4, 4, this); + } + + // MethodBody classes + else if (token.compareTo("${mb_field_get_method}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod, + mbMangledGetGenerateMethod, 4, 4, this); + } + else if (token.compareTo("${mb_field_parameter_list}") == 0) + { + // <cringe> The code generated by this is ugly... It puts a comma on a line by itself! + // TODO: Find a more elegant solution here sometime... + codeSnippet = fieldMap.size() > 0 ? Utils.createSpaces(42) + "," + CR : ""; + // </cringe> + codeSnippet += fieldMap.parseFieldMap(mbParamListGenerateMethod, + mbMangledParamListGenerateMethod, 42, 4, this); + } + + else if (token.compareTo("${mb_field_passed_parameter_list}") == 0) + { + // <cringe> The code generated by this is ugly... It puts a comma on a line by itself! + // TODO: Find a more elegant solution here sometime... + codeSnippet = fieldMap.size() > 0 ? Utils.createSpaces(42) + "," + CR : ""; + // </cringe> + codeSnippet += fieldMap.parseFieldMap(mbPassedParamListGenerateMethod, + mbMangledPassedParamListGenerateMethod, 42, 4, this); + } + else if (token.compareTo("${mb_field_body_initialize}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbBodyInitGenerateMethod, + mbMangledBodyInitGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_size}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbSizeGenerateMethod, + mbBitSizeGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_encode}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbEncodeGenerateMethod, + mbBitEncodeGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_decode}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbDecodeGenerateMethod, + mbBitDecodeGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${mb_field_to_string}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(mbToStringGenerateMethod, + mbBitToStringGenerateMethod, 8, 4, this); + } + + // PropertyContentHeader classes + else if (token.compareTo("${pch_field_list_size}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(pchSizeGenerateMethod, + pchBitSizeGenerateMethod, 12, 4, this); + } + else if (token.compareTo("${pch_field_list_payload}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(pchEncodeGenerateMethod, + pchBitEncodeGenerateMethod, 12, 4, this); + } + else if (token.compareTo("${pch_field_list_decode}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(pchDecodeGenerateMethod, + pchBitDecodeGenerateMethod, 12, 4, this); + } + else if (token.compareTo("${pch_get_compact_property_flags}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(pchGetPropertyFlagsGenerateMethod, + pchBitGetPropertyFlagsGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${pch_set_compact_property_flags}") == 0) + { + codeSnippet = fieldMap.parseFieldMapOrdinally(pchSetPropertyFlagsGenerateMethod, + pchBitSetPropertyFlagsGenerateMethod, 8, 4, this); + } + else if (token.compareTo("${pch_field_clear_methods}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(pchClearGenerateMethod, + pchMangledClearGenerateMethod, 4, 4, this); + } + else if (token.compareTo("${pch_field_get_methods}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(pchGetGenerateMethod, + pchMangledGetGenerateMethod, 4, 4, this); + } + else if (token.compareTo("${pch_field_set_methods}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(pchSetGenerateMethod, + pchMangledSetGenerateMethod, 4, 4, this); + } + + 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) + { + 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(); @@ -686,146 +739,157 @@ public class JavaGenerator extends Generator if (token.compareTo("${const_get_method}") == 0) { - codeSnippet = generateConstantGetMethods(constantSet, 4, 4); + codeSnippet = generateConstantGetMethods(constantSet, 4, 4); } - + else // Oops! { throw new AmqpTemplateException("Template token " + token + " unknown."); } sb.insert(listMarkerStartIndex, codeSnippet); + } + + // === Protected and private helper functions unique to Java implementation === + + // Methods used for generation of code snippets called from the field map parsers + + // Common methods + + protected String generateFieldDeclaration(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + "public " + codeType + " " + field.getName() + + "; // AMQP version(s): " + versionSet + CR; + } + + protected String generateMangledFieldDeclaration(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(Utils.createSpaces(indentSize) + "public " + codeType + " " + + field.getName() + "_" + (domainCntr++) + "; // AMQP Version(s): " + versionSet + + CR); + } + return sb.toString(); + } + + protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + + Iterator<Integer> iItr = indexMap.keySet().iterator(); + while (iItr.hasNext()) + { + int index = iItr.next(); + AmqpVersionSet versionSet = indexMap.get(index); + Iterator<AmqpVersion> vItr = versionSet.iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + sb.append(indent + mapName + "( (byte) " + version.getMajor() + ", (byte) " + version.getMinor() + ", " + index + ");" + CR); + } } - - - // === Protected and private helper functions unique to Java implementation === - - // Methods used for generation of code snippets called from the field map parsers - - // Common methods - - protected String generateFieldDeclaration(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + "public " + codeType + " " + field.name + - "; // AMQP version(s): " + versionSet + cr; - } - - protected String generateMangledFieldDeclaration(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(Utils.createSpaces(indentSize) + "public " + codeType + " " + - field.name + "_" + (domainCntr++) + "; // AMQP Version(s): " + versionSet + - cr); - } - return sb.toString(); - } - - protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - Iterator<Integer> iItr = indexMap.keySet().iterator(); - while (iItr.hasNext()) - { - int index = iItr.next(); - AmqpVersionSet versionSet = indexMap.get(index); - Iterator<AmqpVersion> vItr = versionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - sb.append(indent + mapName + "( (byte) " + version.getMajor() +", (byte) " + version.getMinor() + ", " + index + ");" + cr); - } - } - return sb.toString(); - } - - protected String generateRegistry(AmqpModel model, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - - for (String className : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(className); - for (String methodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(methodName); - for (AmqpVersion version : globalVersionSet) - { - // Find class and method index for this version (if it exists) - try - { - int classIndex = findIndex(thisClass.indexMap, version); - int methodIndex = findIndex(method.indexMap, version); - sb.append(indent + "registerMethod(" + cr); - sb.append(indent + tab + "(short)" + classIndex + - ", (short)" + methodIndex + ", (byte)" + version.getMajor() + - ", (byte)" + version.getMinor() + ", " + cr); - sb.append(indent + tab + Utils.firstUpper(thisClass.name) + - Utils.firstUpper(method.name) + "Body.getFactory());" + cr); - } - catch (Exception e) {} // Ignore - } - } - } - return sb.toString(); - } - - protected int findIndex(TreeMap<Integer, AmqpVersionSet> map, AmqpVersion version) - throws Exception - { - Iterator<Integer> iItr = map.keySet().iterator(); - while (iItr.hasNext()) - { - int index = iItr.next(); - AmqpVersionSet versionSet = map.get(index); - if (versionSet.contains(version)) - return index; - } - throw new Exception("Index not found"); - } - + return sb.toString(); + } + + protected String generateRegistry(AmqpModel model, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + + for (String className : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(className); + for (String methodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(methodName); + for (AmqpVersion version : model.getVersionSet()) + { + // Find class and method index for this version (if it exists) + try + { + int classIndex = findIndex(thisClass.getIndexMap(), version); + int methodIndex = findIndex(method.getIndexMap(), version); + sb.append(indent + "registerMethod(" + CR); + sb.append(indent + tab + "(short)" + classIndex + + ", (short)" + methodIndex + ", (byte)" + version.getMajor() + + ", (byte)" + version.getMinor() + ", " + CR); + sb.append(indent + tab + Utils.firstUpper(thisClass.getName()) + + Utils.firstUpper(method.getName()) + "Body.getFactory());" + CR); + } + catch (Exception e) + { + } // Ignore + } + } + } + return sb.toString(); + } + + protected int findIndex(TreeMap<Integer, AmqpVersionSet> map, AmqpVersion version) + { + Iterator<Integer> iItr = map.keySet().iterator(); + while (iItr.hasNext()) + { + int index = iItr.next(); + AmqpVersionSet versionSet = map.get(index); + if (versionSet.contains(version)) + { + return index; + } + } + throw new IllegalArgumentException("Index not found"); + } + // Methods for AmqpConstants class - + + + public String prepareConstantName(String constantName) + { + return upperCaseName(constantName); + } + + protected String generateConstantGetMethods(AmqpConstantSet constantSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - Iterator<AmqpConstant> cItr = constantSet.iterator(); - while (cItr.hasNext()) + + for (AmqpConstant constant : constantSet.getContstants()) { - AmqpConstant constant = cItr.next(); - if (constant.isVersionConsistent(globalVersionSet)) + + if (constant.isVersionConsistent(constantSet.getVersionSet())) { // return a constant String value = constant.firstKey(); - sb.append(indent + "public static String " + constant.name + "() { return \"" + - constant.firstKey() + "\"; }" + cr); if (Utils.containsOnlyDigits(value)) { - sb.append(indent + "public static int " + constant.name + "AsInt() { return " + - constant.firstKey() + "; }" + cr); + sb.append(indent + "public static final int " + constant.getName() + " = " + + constant.firstKey() + ";" + CR); } - if (Utils.containsOnlyDigitsAndDecimal(value)) + else if (Utils.containsOnlyDigitsAndDecimal(value)) { - sb.append(indent + "public static double " + constant.name + "AsDouble() { return (double)" + - constant.firstKey() + "; }" + cr); + sb.append(indent + "public static double " + constant.getName() + " = " + + constant.firstKey() + "; " + CR); } - sb.append(cr); + else + { + sb.append(indent + "public static String " + constant.getName() + " = " + + constant.firstKey() + "\"; " + CR); + + } + sb.append(CR); } else { @@ -833,23 +897,22 @@ public class JavaGenerator extends Generator sb.append(generateVersionDependentGet(constant, "String", "", "\"", "\"", indentSize, tabSize)); sb.append(generateVersionDependentGet(constant, "int", "AsInt", "", "", indentSize, tabSize)); sb.append(generateVersionDependentGet(constant, "double", "AsDouble", "(double)", "", indentSize, tabSize)); - sb.append(cr); - } - } - return sb.toString(); + sb.append(CR); + } + } + return sb.toString(); } - + protected String generateVersionDependentGet(AmqpConstant constant, - String methodReturnType, String methodNameSuffix, String returnPrefix, String returnPostfix, - int indentSize, int tabSize) - throws AmqpTypeMappingException + String methodReturnType, String methodNameSuffix, String returnPrefix, String returnPostfix, + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - sb.append(indent + "public static " + methodReturnType + " " + constant.name + - methodNameSuffix + "(byte major, byte minor) throws AMQProtocolVersionException" + cr); - sb.append(indent + "{" + cr); + sb.append(indent + "public static " + methodReturnType + " " + constant.getName() + + methodNameSuffix + "(byte major, byte minor) throws AMQProtocolVersionException" + CR); + sb.append(indent + "{" + CR); boolean first = true; Iterator<String> sItr = constant.keySet().iterator(); while (sItr.hasNext()) @@ -857,838 +920,907 @@ public class JavaGenerator extends Generator String value = sItr.next(); AmqpVersionSet versionSet = constant.get(value); sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) + - ")" + cr); - sb.append(indent + tab + "{" + cr); + ")" + CR); + sb.append(indent + tab + "{" + CR); if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(value)) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); } else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(value)) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); } else { - sb.append(indent + tab + tab + "return " + returnPrefix + value + returnPostfix + ";" + cr); + sb.append(indent + tab + tab + "return " + returnPrefix + value + returnPostfix + ";" + CR); } - sb.append(indent + tab + "}" + cr); + sb.append(indent + tab + "}" + CR); first = false; } - sb.append(indent + tab + "else" + cr); - sb.append(indent + tab + "{" + cr); + sb.append(indent + tab + "else" + CR); + sb.append(indent + tab + "{" + CR); sb.append(indent + tab + tab + "throw new AMQProtocolVersionException(\"Constant \\\"" + - constant.name + "\\\" \" +" + cr); + constant.getName() + "\\\" \" +" + CR); sb.append(indent + tab + tab + tab + - "\"is undefined for AMQP version \" + major + \"-\" + minor + \".\");" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + "}" + cr); - return sb.toString(); + "\"is undefined for AMQP version \" + major + \"-\" + minor + \".\");" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + "}" + CR); + return sb.toString(); } - + protected String generateConstantDeclarationException(String name, String methodReturnType, - int indentSize, int tabSize) + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); sb.append(indent + "throw new AMQProtocolVersionException(\"Constant \\\"" + - name + "\\\" \" +" + cr); + name + "\\\" \" +" + CR); sb.append(indent + tab + "\"cannot be converted to type " + methodReturnType + - " for AMQP version \" + major + \"-\" + minor + \".\");" + cr); - return sb.toString(); - } - - // Methods for MessageBody classes - protected String generateMbGetMethod(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + "public " + codeType + " get" + - Utils.firstUpper(field.name) + "() { return " + field.name + "; }" + - cr; - } - - protected String generateMbMangledGetMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(cr); - sb.append(indent + "public <T> T get" + Utils.firstUpper(field.name) + - "(Class<T> classObj) throws AMQProtocolVersionException" + cr); - sb.append(indent + "{" + cr); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(indent + tab + "if (classObj.equals(" + codeType + - ".class)) // AMQP Version(s): " + versionSet + cr); - sb.append(indent + tab + tab + "return (T)(Object)" + field.name + "_" + - (domainCntr++) + ";" + cr); - } - sb.append(indent + tab + - "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + - cr + " \"field \\\"" + field.name + - "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generateMbParamList(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + codeType + " " + field.name + - (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + cr; - } - - - protected String generateMbPassedParamList(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + field.name + - (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + cr; - } - - - protected String generateMbMangledParamList(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(Utils.createSpaces(indentSize) + codeType + " " + field.name + "_" + - (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + - versionSet + cr); - } - return sb.toString(); - } - - protected String generateMbMangledPassedParamList(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - sb.append(Utils.createSpaces(indentSize) + field.name + "_" + - (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + - versionSet + cr); - } - return sb.toString(); - } - - - protected String generateMbBodyInit(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + "this." + field.name + " = " + field.name + - ";" + cr; - } - - protected String generateMbMangledBodyInit(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - dItr.next(); - sb.append(Utils.createSpaces(indentSize) + "this." + field.name + "_" + domainCntr + - " = " + field.name + "_" + (domainCntr++) + ";" + cr); - } - return sb.toString(); - } - - protected String generateMbFieldSize(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldName) + - "; // " + fieldName + ": " + domainType + cr); - return sb.toString(); - } - - protected String generateMbBitArrayFieldSize(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - int numBytes = ((bitFieldList.size() - 1) / 8) + 1; - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - sb.append(Utils.createSpaces(indentSize) + "size += " + - typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + - "; // " + comment + cr); - return sb.toString(); - } - - protected String generateMbFieldEncode(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) + - "; // " + fieldName + ": " + domain + cr); - return sb.toString(); - } - - protected String generateMbBitFieldEncode(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - - StringBuilder sb = new StringBuilder(); - int i = 0; - while(i <bitFieldList.size()) - { - - StringBuilder line = new StringBuilder(); - - for (int j=0; i<bitFieldList.size() && j<8; i++, j++) - { - if (j != 0) - { - line.append(", "); - } - line.append(bitFieldList.get(i)); - } - - sb.append(indent + - typeMap.get("bit").encodeExpression.replaceAll("#", line.toString()) + ";" + cr); - } - return sb.toString(); - } - - protected String generateMbFieldDecode(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - typeMap.get(domain).decodeExpression.replaceAll("#", fieldName) + - "; // " + fieldName + ": " + domain + cr); - return sb.toString(); - } - - protected String generateMbBitFieldDecode(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - - StringBuilder sb = new StringBuilder(indent); - sb.append("byte packedValue;"); - sb.append(cr); - - // RG HERE! - - int i = 0; - while(i < bitFieldList.size()) - { - sb.append(indent + "packedValue = EncodingUtils.readByte(buffer);" + cr); - - for(int j = 0; i < bitFieldList.size() && j < 8; i++, j++) - { - sb.append(indent + bitFieldList.get(i) + " = ( packedValue & (byte) (1 << " + j + ") ) != 0;" + cr); - } - } - return sb.toString(); - } - - protected String generateMbFieldToString(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - "buf.append(\" " + fieldName + ": \" + " + fieldName + ");" + cr); - return sb.toString(); - } - - protected String generateMbBitFieldToString(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - for (int i=0; i<bitFieldList.size(); i++) - { - String bitFieldName = bitFieldList.get(i); - sb.append(indent + "buf.append(\" " + bitFieldName + ": \" + " + bitFieldName + - ");" + cr); - } - return sb.toString(); - } - - // Methods for PropertyContentHeader classes - - protected String generatePchClearMethod(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - // This is one case where the ordinal info is the only significant factor, - // the domain info plays no part. Defer to the mangled version; the code would be - // identical anyway... - return generatePchMangledClearMethod(field, indentSize, tabSize, nextFlag); - } - - protected String generatePchMangledClearMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "public void clear" + Utils.firstUpper(field.name) + - "()" + cr); - sb.append(indent + "{" + cr); - - // If there is more than one ordinal for this field or the ordinal does not - // apply to all known versions, then we need to generate version checks so - // we know which fieldProperty to clear. - if (field.ordinalMap.size() == 1 && - field.ordinalMap.get(field.ordinalMap.firstKey()).size() == globalVersionSet.size()) - { - int ordinal = field.ordinalMap.firstKey(); - sb.append(indent + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + "propertyFlags[" + ordinal + "] = false;" + cr); - } - else - { - Iterator<Integer> oItr = field.ordinalMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - AmqpVersionSet versionSet = field.ordinalMap.get(ordinal); - sb.append(indent + tab); - if (ordinal != field.ordinalMap.firstKey()) - sb.append("else "); - sb.append("if ("); - sb.append(generateVersionCheck(versionSet)); - sb.append(")" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = false;" + cr); - sb.append(indent + tab + "}" + cr); - } - } - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchGetMethod(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(indent + "public " + codeType + " get" + - Utils.firstUpper(field.name) + "()" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "decodeIfNecessary();" + cr); - sb.append(indent + tab + "return " + field.name + ";" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchMangledGetMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(indent + "public <T> T get" + - Utils.firstUpper(field.name) + - "(Class<T> classObj) throws AMQProtocolVersionException" + cr); - sb.append(indent + "{" + cr); - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(indent + tab + "if (classObj.equals(" + codeType + - ".class)) // AMQP Version(s): " + versionSet + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "decodeIfNecessary();" + cr); - sb.append(indent + tab + tab + "return (T)(Object)" + field.name + "_" + - (domainCntr++) + ";" + cr); - sb.append(indent + tab + "}" + cr); - } - sb.append(indent + tab + - "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + - cr + " \"field \\\"" + field.name + - "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchSetMethod(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "public void set" + Utils.firstUpper(field.name) + - "(" + codeType + " " + field.name + ")" + cr); - sb.append(indent + "{" + cr); - - // If there is more than one ordinal for this field or the ordinal does not - // apply to all known versions, then we need to generate version checks so - // we know which fieldProperty to clear. - if (field.ordinalMap.size() == 1 && - field.ordinalMap.get(field.ordinalMap.firstKey()).size() == globalVersionSet.size()) - { - int ordinal = field.ordinalMap.firstKey(); - sb.append(indent + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + "propertyFlags[" + ordinal + "] = true;" + cr); - sb.append(indent + tab + "this." + field.name + " = " + field.name + ";" + cr); - } - else - { - Iterator<Integer> oItr = field.ordinalMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - AmqpVersionSet oVersionSet = field.ordinalMap.get(ordinal); - sb.append(indent + tab); - if (ordinal != field.ordinalMap.firstKey()) - sb.append("else "); - sb.append("if ("); - sb.append(generateVersionCheck(oVersionSet)); - sb.append(")" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + cr); - sb.append(indent + tab + tab + "this." + field.name + " = " + field.name + ";" + cr); - sb.append(indent + tab + "}" + cr); - } - } - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchMangledSetMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - - Iterator<String> dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - - // Find ordinal with matching version - AmqpVersionSet commonVersionSet = new AmqpVersionSet(); - Iterator<Integer> oItr = field.ordinalMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - AmqpVersionSet oVersionSet = field.ordinalMap.get(ordinal); - Iterator<AmqpVersion> vItr = oVersionSet.iterator(); - boolean first = true; - while (vItr.hasNext()) - { - AmqpVersion thisVersion = vItr.next(); - if (versionSet.contains(thisVersion)) - commonVersionSet.add(thisVersion); - } - if (!commonVersionSet.isEmpty()) - { - sb.append(indent + "public void set" + Utils.firstUpper(field.name) + - "(" + codeType + " " + field.name + ")" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab); - if (!first) - sb.append("else "); - sb.append("if ("); - sb.append(generateVersionCheck(commonVersionSet)); - sb.append(")" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + cr); - sb.append(indent + tab + tab + "this." + field.name + "_" + (domainCntr++) + - " = " + field.name + ";" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - protected String generatePchFieldSize(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(indent + "if (propertyFlags[" + ordinal + "]) // " + - fieldName + ": " + domainType + cr); - sb.append(indent + Utils.createSpaces(tabSize) + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldName) + ";" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchBitArrayFieldSize(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - StringBuffer sb = new StringBuffer(); - - if (bitFieldList.size() == 1) // single bit - { - sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + comment + cr); - sb.append(indent + tab + "size += " + - typeMap.get("bit").size.replaceAll("~", "1") + ";" + cr); - } - else // multiple bits - up to 8 are combined into one byte - { - String bitCntrName = "bitCntr_" + ordinal; - int startOrdinal = ordinal - bitFieldList.size(); - sb.append(indent + "// " + comment + cr); - sb.append(indent + "int " + bitCntrName + " = 0;" + cr); - sb.append(indent + "for (int i=" + startOrdinal + "; i<" + ordinal + "; i++)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "if (propertyFlags[i])" + cr); - sb.append(indent + tab + tab + bitCntrName + "++;" + cr); - sb.append(indent + "}" + cr); - sb.append(indent + "size += " + - typeMap.get("bit").size.replaceAll("~", bitCntrName + - " > 0 ? ((" + bitCntrName + " - 1) / 8) + 1 : 0") + ";" + cr); - } - sb.append(cr); - return sb.toString(); - } - - protected String generatePchFieldEncode(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + - domainType + cr); - sb.append(indent + Utils.createSpaces(tabSize) + - typeMap.get(domainType).encodeExpression.replaceAll("#", fieldName) + ";" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchBitFieldEncode(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - StringBuffer sb = new StringBuffer(); - - if (bitFieldList.size() == 1) // single bit - { - sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + - bitFieldList.get(0) + ": bit" + cr); - sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#", - "new boolean[] {" + bitFieldList.get(0) + "}") + ";" + cr); - } - else // multiple bits - up to 8 are combined into one byte - { - int startOrdinal = ordinal - bitFieldList.size(); - String bitCntrName = "bitCntr" + startOrdinal; - sb.append(indent + "// " + comment + cr); - sb.append(indent + "int " + bitCntrName + " = 0;" + cr); - sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "if (propertyFlags[i])" + cr); - sb.append(indent + tab + tab + bitCntrName + "++;" + cr); - sb.append(indent + "}" + cr); - sb.append(indent + "if (" + bitCntrName + " > 0) // Are any of the property bits set?" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "boolean[] fullBitArray = new boolean[] { "); - for (int i=0; i<bitFieldList.size(); i++) - { - if (i != 0) - sb.append(", "); - sb.append(bitFieldList.get(i)); - } - sb.append(" };" + cr); - sb.append(indent + tab + "boolean[] flaggedBitArray = new boolean[" +bitCntrName + - "];" + cr); - sb.append(indent + tab + bitCntrName + " = 0;" + cr); - sb.append(indent + tab + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + - "; i++)" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab+ "if (propertyFlags[i])" + cr); - sb.append(indent + tab + tab + tab + "flaggedBitArray[" + bitCntrName + - "++] = fullBitArray[i];" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#", - "flaggedBitArray") + ";" + cr); - sb.append(indent + "}" + cr); - } - sb.append(cr); - return sb.toString(); - } - - protected String generatePchFieldDecode(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + - domainType + cr); - sb.append(indent + Utils.createSpaces(tabSize) + - typeMap.get(domainType).decodeExpression.replaceAll("#", fieldName) + ";" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchBitFieldDecode(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - StringBuffer sb = new StringBuffer(); - - if (bitFieldList.size() == 1) // single bit - { - sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + - bitFieldList.get(0) + ": bit" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#", - "boolean[] flaggedBitArray") + ";" + cr); - sb.append(indent + tab + bitFieldList.get(0) + " = flaggedBitArray[0];" + cr); - sb.append(indent + "}" + cr); - } - else // multiple bits - up to 8 are combined into one byte - { - int startOrdinal = ordinal - bitFieldList.size(); - String bitCntr = "bitCntr" + startOrdinal; - sb.append(indent + "// " + comment + cr); - sb.append(indent + "int " + bitCntr + " = 0;" + cr); - sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "if (propertyFlags[i])" + cr); - sb.append(indent + tab + tab + bitCntr + "++;" + cr); - sb.append(indent + "}" + cr); - sb.append(indent + "if (" + bitCntr + " > 0) // Are any of the property bits set?" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#", - "boolean[] flaggedBitArray") + ";" + cr); - sb.append(indent + tab + bitCntr + " = 0;" + cr); - for (int i=0; i<bitFieldList.size(); i++) - { - sb.append(indent + tab + "if (propertyFlags[" + (startOrdinal + i) + "])" + cr); - sb.append(indent + tab + tab + bitFieldList.get(i) + " = flaggedBitArray[" + - bitCntr + "++];" + cr); - } - sb.append(indent + "}" + cr); - } - - sb.append(cr); - return sb.toString(); - } - - protected String generatePchGetPropertyFlags(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - int word = ordinal / 15; - int bit = 15 - (ordinal % 15); - sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + - domainType + cr); - sb.append(indent + tab + "compactPropertyFlags[" + word + "] |= (1 << " + - bit + ");" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchBitGetPropertyFlags(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - int startOrdinal = ordinal - bitFieldList.size(); - - for (int i=0; i<bitFieldList.size(); i++) - { - int thisOrdinal = startOrdinal + i; - int word = thisOrdinal / 15; - int bit = 15 - (thisOrdinal % 15); - sb.append(indent + "if (propertyFlags[" + thisOrdinal + "])" + cr); - sb.append(indent + tab + "compactPropertyFlags[" + word + - "] |= (1 << " + bit + ");" + cr); - } - - sb.append(cr); - return sb.toString(); - } - - protected String generatePchSetPropertyFlags(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - int word = ordinal / 15; - int bit = 15 - (ordinal % 15); - sb.append(indent + "propertyFlags[" + ordinal + "] = (compactPropertyFlags[" + - word + "] & (1 << " + bit + ")) > 0;" + cr); - return sb.toString(); - } - - protected String generatePchBitSetPropertyFlags(ArrayList<String> bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - int startOrdinal = ordinal - bitFieldList.size(); - - for (int i=0; i<bitFieldList.size(); i++) - { - int thisOrdinal = startOrdinal + i; - int word = thisOrdinal / 15; - int bit = 15 - (thisOrdinal % 15); - sb.append(indent + "propertyFlags[" + thisOrdinal + "] = (compactPropertyFlags[" + - word + "] & (1 << " + bit + ")) > 0;" + cr); - } - return sb.toString(); - } - - private String generatePchPropertyFlagsDeclare() - { - return "private boolean[] propertyFlags;"; - } - - private String generatePchPropertyFlagsInitializer(int totNumFields) - { - return "propertyFlags = new boolean[" + totNumFields + "];"; - } - - private String generatePchCompactPropertyFlagsInitializer(AmqpClass thisClass, int indentSize, - int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - Iterator<AmqpVersion> vItr = globalVersionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - int numBytes = ((thisClass.fieldMap.getNumFields(version) - 1) / 15) + 1; - - sb.append(indent); - if (!version.equals(globalVersionSet.first())) - sb.append("else "); - sb.append("if ( major == " + version.getMajor() + " && minor == " + - version.getMinor() + " )" + cr); - sb.append(indent + tab + "compactPropertyFlags = new int[] { "); - for (int i=0; i<numBytes; i++) - { - if (i!= 0) - sb.append(", "); - sb.append(i < numBytes - 1 ? "1" : "0"); // Set the "continue" flag where required - } - sb.append(" };" + cr); - } - return sb.toString(); - } - - private String generatePchCompactPropertyFlagsCheck(AmqpClass thisClass, int indentSize, - int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - Iterator<AmqpVersion> vItr = globalVersionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - int numFields = thisClass.fieldMap.getNumFields(version); - int numBytes = ((numFields - 1) / 15) + 1; - - sb.append(indent); - if (!version.equals(globalVersionSet.first())) - sb.append("else "); - sb.append("if ( major == " + version.getMajor() + " && minor == " + - version.getMinor() + " && compactPropertyFlags.length != " + numBytes + " )" + cr); - sb.append(indent + tab + - "throw new AMQProtocolVersionException(\"Property flag array size mismatch:\" +" + cr); - sb.append(indent + tab + tab + "\"(Size found: \" + compactPropertyFlags.length +" + cr); - sb.append(indent + tab + tab + "\") Version " + version + " has " + numFields + - " fields which requires an int array of size " + numBytes + ".\");" + cr); - } - return sb.toString(); - } - - private String generateVersionCheck(AmqpVersionSet v) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - AmqpVersion[] versionArray = new AmqpVersion[v.size()]; - v.toArray(versionArray); - for (int i=0; i<versionArray.length; i++) - { - if (i != 0) - sb.append(" || "); - if (versionArray.length > 1) - sb.append("("); - sb.append("major == (byte)" + versionArray[i].getMajor() + " && minor == (byte)" + - versionArray[i].getMinor()); - if (versionArray.length > 1) - sb.append(")"); - } - return sb.toString(); - } - - 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(); - } + " for AMQP version \" + major + \"-\" + minor + \".\");" + CR); + return sb.toString(); + } + + // Methods for MessageBody classes + protected String generateMbGetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + "public " + codeType + " get" + + Utils.firstUpper(field.getName()) + "() { return " + field.getName() + "; }" + + CR; + } + + protected String generateMbMangledGetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(CR); + sb.append(indent + "public <T> T get" + Utils.firstUpper(field.getName()) + + "(Class<T> classObj) throws AMQProtocolVersionException" + CR); + sb.append(indent + "{" + CR); + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(indent + tab + "if (classObj.equals(" + codeType + + ".class)) // AMQP Version(s): " + versionSet + CR); + sb.append(indent + tab + tab + "return (T)(Object)" + field.getName() + "_" + + (domainCntr++) + ";" + CR); + } + sb.append(indent + tab + + "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + + CR + " \"field \\\"" + field.getName() + + "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generateMbParamList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + codeType + " " + field.getName() + + (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + CR; + } + + + protected String generateMbPassedParamList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + field.getName() + + (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + CR; + } + + + protected String generateMbMangledParamList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(Utils.createSpaces(indentSize) + codeType + " " + field.getName() + "_" + + (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + + versionSet + CR); + } + return sb.toString(); + } + + protected String generateMbMangledPassedParamList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + sb.append(Utils.createSpaces(indentSize) + field.getName() + "_" + + (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + + versionSet + CR); + } + return sb.toString(); + } + + + protected String generateMbBodyInit(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + "this." + field.getName() + " = " + field.getName() + + ";" + CR; + } + + protected String generateMbMangledBodyInit(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + dItr.next(); + sb.append(Utils.createSpaces(indentSize) + "this." + field.getName() + "_" + domainCntr + + " = " + field.getName() + "_" + (domainCntr++) + ";" + CR); + } + return sb.toString(); + } + + protected String generateMbFieldSize(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldName) + + "; // " + fieldName + ": " + domainType + CR); + return sb.toString(); + } + + protected String generateMbBitArrayFieldSize(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + sb.append(Utils.createSpaces(indentSize) + "size += " + + typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + + "; // " + comment + CR); + return sb.toString(); + } + + protected String generateMbFieldEncode(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) + + "; // " + fieldName + ": " + domain + CR); + return sb.toString(); + } + + protected String generateMbBitFieldEncode(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + + StringBuilder sb = new StringBuilder(); + int i = 0; + while (i < bitFieldList.size()) + { + + StringBuilder line = new StringBuilder(); + + for (int j = 0; i < bitFieldList.size() && j < 8; i++, j++) + { + if (j != 0) + { + line.append(", "); + } + line.append(bitFieldList.get(i)); + } + + sb.append(indent + + typeMap.get("bit").encodeExpression.replaceAll("#", line.toString()) + ";" + CR); + } + return sb.toString(); + } + + protected String generateMbFieldDecode(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + typeMap.get(domain).decodeExpression.replaceAll("#", fieldName) + + "; // " + fieldName + ": " + domain + CR); + return sb.toString(); + } + + protected String generateMbBitFieldDecode(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + + StringBuilder sb = new StringBuilder(indent); + sb.append("byte packedValue;"); + sb.append(CR); + + // RG HERE! + + int i = 0; + while (i < bitFieldList.size()) + { + sb.append(indent + "packedValue = EncodingUtils.readByte(buffer);" + CR); + + for (int j = 0; i < bitFieldList.size() && j < 8; i++, j++) + { + sb.append(indent + bitFieldList.get(i) + " = ( packedValue & (byte) (1 << " + j + ") ) != 0;" + CR); + } + } + return sb.toString(); + } + + protected String generateMbFieldToString(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + "buf.append(\" " + fieldName + ": \" + " + fieldName + ");" + CR); + return sb.toString(); + } + + protected String generateMbBitFieldToString(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < bitFieldList.size(); i++) + { + String bitFieldName = bitFieldList.get(i); + sb.append(indent + "buf.append(\" " + bitFieldName + ": \" + " + bitFieldName + + ");" + CR); + } + return sb.toString(); + } + + // Methods for PropertyContentHeader classes + + protected String generatePchClearMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + // This is one case where the ordinal info is the only significant factor, + // the domain info plays no part. Defer to the mangled version; the code would be + // identical anyway... + return generatePchMangledClearMethod(field, indentSize, tabSize, nextFlag); + } + + protected String generatePchMangledClearMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "public void clear" + Utils.firstUpper(field.getName()) + + "()" + CR); + sb.append(indent + "{" + CR); + + // If there is more than one ordinal for this field or the ordinal does not + // apply to all known versions, then we need to generate version checks so + // we know which fieldProperty to clear. + if (field.getOrdinalMap().size() == 1 && + field.getOrdinalMap().get(field.getOrdinalMap().firstKey()).size() == field.getVersionSet().size()) + { + int ordinal = field.getOrdinalMap().firstKey(); + sb.append(indent + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + "propertyFlags[" + ordinal + "] = false;" + CR); + } + else + { + Iterator<Integer> oItr = field.getOrdinalMap().keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + AmqpVersionSet versionSet = field.getOrdinalMap().get(ordinal); + sb.append(indent + tab); + if (ordinal != field.getOrdinalMap().firstKey()) + { + sb.append("else "); + } + sb.append("if ("); + sb.append(generateVersionCheck(versionSet)); + sb.append(")" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = false;" + CR); + sb.append(indent + tab + "}" + CR); + } + } + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchGetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(indent + "public " + codeType + " get" + + Utils.firstUpper(field.getName()) + "()" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "decodeIfNecessary();" + CR); + sb.append(indent + tab + "return " + field.getName() + ";" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchMangledGetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(indent + "public <T> T get" + + Utils.firstUpper(field.getName()) + + "(Class<T> classObj) throws AMQProtocolVersionException" + CR); + sb.append(indent + "{" + CR); + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(indent + tab + "if (classObj.equals(" + codeType + + ".class)) // AMQP Version(s): " + versionSet + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "decodeIfNecessary();" + CR); + sb.append(indent + tab + tab + "return (T)(Object)" + field.getName() + "_" + + (domainCntr++) + ";" + CR); + sb.append(indent + tab + "}" + CR); + } + sb.append(indent + tab + + "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + + CR + " \"field \\\"" + field.getName() + + "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchSetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "public void set" + Utils.firstUpper(field.getName()) + + "(" + codeType + " " + field.getName() + ")" + CR); + sb.append(indent + "{" + CR); + + // If there is more than one ordinal for this field or the ordinal does not + // apply to all known versions, then we need to generate version checks so + // we know which fieldProperty to clear. + if (field.getOrdinalMap().size() == 1 && + field.getOrdinalMap().get(field.getOrdinalMap().firstKey()).size() == field.getVersionSet().size()) + { + int ordinal = field.getOrdinalMap().firstKey(); + sb.append(indent + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + "propertyFlags[" + ordinal + "] = true;" + CR); + sb.append(indent + tab + "this." + field.getName() + " = " + field.getName() + ";" + CR); + } + else + { + Iterator<Integer> oItr = field.getOrdinalMap().keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + AmqpVersionSet oVersionSet = field.getOrdinalMap().get(ordinal); + sb.append(indent + tab); + if (ordinal != field.getOrdinalMap().firstKey()) + { + sb.append("else "); + } + sb.append("if ("); + sb.append(generateVersionCheck(oVersionSet)); + sb.append(")" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + CR); + sb.append(indent + tab + tab + "this." + field.getName() + " = " + field.getName() + ";" + CR); + sb.append(indent + tab + "}" + CR); + } + } + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchMangledSetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + + Iterator<String> dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + + // Find ordinal with matching version + AmqpVersionSet commonVersionSet = new AmqpVersionSet(); + Iterator<Integer> oItr = field.getOrdinalMap().keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + AmqpVersionSet oVersionSet = field.getOrdinalMap().get(ordinal); + Iterator<AmqpVersion> vItr = oVersionSet.iterator(); + boolean first = true; + while (vItr.hasNext()) + { + AmqpVersion thisVersion = vItr.next(); + if (versionSet.contains(thisVersion)) + { + commonVersionSet.add(thisVersion); + } + } + if (!commonVersionSet.isEmpty()) + { + sb.append(indent + "public void set" + Utils.firstUpper(field.getName()) + + "(" + codeType + " " + field.getName() + ")" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab); + if (!first) + { + sb.append("else "); + } + sb.append("if ("); + sb.append(generateVersionCheck(commonVersionSet)); + sb.append(")" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + CR); + sb.append(indent + tab + tab + "this." + field.getName() + "_" + (domainCntr++) + + " = " + field.getName() + ";" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + first = false; + } + } + } + return sb.toString(); + } + + protected String generatePchFieldSize(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(indent + "if (propertyFlags[" + ordinal + "]) // " + + fieldName + ": " + domainType + CR); + sb.append(indent + Utils.createSpaces(tabSize) + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldName) + ";" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitArrayFieldSize(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + StringBuffer sb = new StringBuffer(); + + if (bitFieldList.size() == 1) // single bit + { + sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + comment + CR); + sb.append(indent + tab + "size += " + + typeMap.get("bit").size.replaceAll("~", "1") + ";" + CR); + } + else // multiple bits - up to 8 are combined into one byte + { + String bitCntrName = "bitCntr_" + ordinal; + int startOrdinal = ordinal - bitFieldList.size(); + sb.append(indent + "// " + comment + CR); + sb.append(indent + "int " + bitCntrName + " = 0;" + CR); + sb.append(indent + "for (int i=" + startOrdinal + "; i<" + ordinal + "; i++)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + bitCntrName + "++;" + CR); + sb.append(indent + "}" + CR); + sb.append(indent + "size += " + + typeMap.get("bit").size.replaceAll("~", bitCntrName + + " > 0 ? ((" + bitCntrName + " - 1) / 8) + 1 : 0") + ";" + CR); + } + sb.append(CR); + return sb.toString(); + } + + protected String generatePchFieldEncode(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + + domainType + CR); + sb.append(indent + Utils.createSpaces(tabSize) + + typeMap.get(domainType).encodeExpression.replaceAll("#", fieldName) + ";" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitFieldEncode(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + StringBuffer sb = new StringBuffer(); + + if (bitFieldList.size() == 1) // single bit + { + sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + + bitFieldList.get(0) + ": bit" + CR); + sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#", + "new boolean[] {" + bitFieldList.get(0) + "}") + ";" + CR); + } + else // multiple bits - up to 8 are combined into one byte + { + int startOrdinal = ordinal - bitFieldList.size(); + String bitCntrName = "bitCntr" + startOrdinal; + sb.append(indent + "// " + comment + CR); + sb.append(indent + "int " + bitCntrName + " = 0;" + CR); + sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + bitCntrName + "++;" + CR); + sb.append(indent + "}" + CR); + sb.append(indent + "if (" + bitCntrName + " > 0) // Are any of the property bits set?" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "boolean[] fullBitArray = new boolean[] { "); + for (int i = 0; i < bitFieldList.size(); i++) + { + if (i != 0) + { + sb.append(", "); + } + sb.append(bitFieldList.get(i)); + } + sb.append(" };" + CR); + sb.append(indent + tab + "boolean[] flaggedBitArray = new boolean[" + bitCntrName + + "];" + CR); + sb.append(indent + tab + bitCntrName + " = 0;" + CR); + sb.append(indent + tab + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + + "; i++)" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + tab + "flaggedBitArray[" + bitCntrName + + "++] = fullBitArray[i];" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#", + "flaggedBitArray") + ";" + CR); + sb.append(indent + "}" + CR); + } + sb.append(CR); + return sb.toString(); + } + + protected String generatePchFieldDecode(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + + domainType + CR); + sb.append(indent + Utils.createSpaces(tabSize) + + typeMap.get(domainType).decodeExpression.replaceAll("#", fieldName) + ";" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitFieldDecode(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + StringBuffer sb = new StringBuffer(); + + if (bitFieldList.size() == 1) // single bit + { + sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + + bitFieldList.get(0) + ": bit" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#", + "boolean[] flaggedBitArray") + ";" + CR); + sb.append(indent + tab + bitFieldList.get(0) + " = flaggedBitArray[0];" + CR); + sb.append(indent + "}" + CR); + } + else // multiple bits - up to 8 are combined into one byte + { + int startOrdinal = ordinal - bitFieldList.size(); + String bitCntr = "bitCntr" + startOrdinal; + sb.append(indent + "// " + comment + CR); + sb.append(indent + "int " + bitCntr + " = 0;" + CR); + sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + bitCntr + "++;" + CR); + sb.append(indent + "}" + CR); + sb.append(indent + "if (" + bitCntr + " > 0) // Are any of the property bits set?" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#", + "boolean[] flaggedBitArray") + ";" + CR); + sb.append(indent + tab + bitCntr + " = 0;" + CR); + for (int i = 0; i < bitFieldList.size(); i++) + { + sb.append(indent + tab + "if (propertyFlags[" + (startOrdinal + i) + "])" + CR); + sb.append(indent + tab + tab + bitFieldList.get(i) + " = flaggedBitArray[" + + bitCntr + "++];" + CR); + } + sb.append(indent + "}" + CR); + } + + sb.append(CR); + return sb.toString(); + } + + protected String generatePchGetPropertyFlags(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + int word = ordinal / 15; + int bit = 15 - (ordinal % 15); + sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + + domainType + CR); + sb.append(indent + tab + "compactPropertyFlags[" + word + "] |= (1 << " + + bit + ");" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitGetPropertyFlags(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + int startOrdinal = ordinal - bitFieldList.size(); + + for (int i = 0; i < bitFieldList.size(); i++) + { + int thisOrdinal = startOrdinal + i; + int word = thisOrdinal / 15; + int bit = 15 - (thisOrdinal % 15); + sb.append(indent + "if (propertyFlags[" + thisOrdinal + "])" + CR); + sb.append(indent + tab + "compactPropertyFlags[" + word + + "] |= (1 << " + bit + ");" + CR); + } + + sb.append(CR); + return sb.toString(); + } + + protected String generatePchSetPropertyFlags(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + int word = ordinal / 15; + int bit = 15 - (ordinal % 15); + sb.append(indent + "propertyFlags[" + ordinal + "] = (compactPropertyFlags[" + + word + "] & (1 << " + bit + ")) > 0;" + CR); + return sb.toString(); + } + + protected String generatePchBitSetPropertyFlags(List<String> bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + int startOrdinal = ordinal - bitFieldList.size(); + + for (int i = 0; i < bitFieldList.size(); i++) + { + int thisOrdinal = startOrdinal + i; + int word = thisOrdinal / 15; + int bit = 15 - (thisOrdinal % 15); + sb.append(indent + "propertyFlags[" + thisOrdinal + "] = (compactPropertyFlags[" + + word + "] & (1 << " + bit + ")) > 0;" + CR); + } + return sb.toString(); + } + + private String generatePchPropertyFlagsDeclare() + { + return "private boolean[] propertyFlags;"; + } + + private String generatePchPropertyFlagsInitializer(int totNumFields) + { + return "propertyFlags = new boolean[" + totNumFields + "];"; + } + + private String generatePchCompactPropertyFlagsInitializer(AmqpClass thisClass, int indentSize, + int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + Iterator<AmqpVersion> vItr = thisClass.getVersionSet().iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + int numBytes = ((thisClass.getFieldMap().getNumFields(version) - 1) / 15) + 1; + + sb.append(indent); + if (!version.equals(thisClass.getVersionSet().first())) + { + sb.append("else "); + } + sb.append("if ( major == " + version.getMajor() + " && minor == " + + version.getMinor() + " )" + CR); + sb.append(indent + tab + "compactPropertyFlags = new int[] { "); + for (int i = 0; i < numBytes; i++) + { + if (i != 0) + { + sb.append(", "); + } + sb.append(i < numBytes - 1 ? "1" : "0"); // Set the "continue" flag where required + } + sb.append(" };" + CR); + } + return sb.toString(); + } + + private String generatePchCompactPropertyFlagsCheck(AmqpClass thisClass, int indentSize, + int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + Iterator<AmqpVersion> vItr = thisClass.getVersionSet().iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + int numFields = thisClass.getFieldMap().getNumFields(version); + int numBytes = ((numFields - 1) / 15) + 1; + + sb.append(indent); + if (!version.equals(thisClass.getVersionSet().first())) + { + sb.append("else "); + } + sb.append("if ( major == " + version.getMajor() + " && minor == " + + version.getMinor() + " && compactPropertyFlags.length != " + numBytes + " )" + CR); + sb.append(indent + tab + + "throw new AMQProtocolVersionException(\"Property flag array size mismatch:\" +" + CR); + sb.append(indent + tab + tab + "\"(Size found: \" + compactPropertyFlags.length +" + CR); + sb.append(indent + tab + tab + "\") Version " + version + " has " + numFields + + " fields which requires an int array of size " + numBytes + ".\");" + CR); + } + return sb.toString(); + } + + private String generateVersionCheck(AmqpVersionSet v) + { + StringBuffer sb = new StringBuffer(); + AmqpVersion[] versionArray = new AmqpVersion[v.size()]; + v.toArray(versionArray); + for (int i = 0; i < versionArray.length; i++) + { + if (i != 0) + { + sb.append(" || "); + } + if (versionArray.length > 1) + { + sb.append("("); + } + sb.append("major == (byte)" + versionArray[i].getMajor() + " && minor == (byte)" + + versionArray[i].getMinor()); + if (versionArray.length > 1) + { + sb.append(")"); + } + } + return sb.toString(); + } + + 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(); + } + + + private String upperCaseName(String name) + { + StringBuffer ccn = new StringBuffer(); + String[] toks = name.split("[-_.\\ ]"); + for (int i = 0; i < toks.length; i++) + { + if (i != 0) + { + ccn.append('_'); + } + ccn.append(toks[i].toUpperCase()); + + + } + return ccn.toString(); + } + + + public static Factory<JavaGenerator> _factoryInstance = new Factory<JavaGenerator>() + { + + public JavaGenerator newInstance() + { + return new JavaGenerator(); + } + }; + + public static Factory<JavaGenerator> getFactory() + { + return _factoryInstance; + } + + + void processModelTemplate(NamedTemplate template, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + } diff --git a/gentools/src/org/apache/qpid/gentools/LanguageConverter.java b/gentools/src/org/apache/qpid/gentools/LanguageConverter.java index cb0a14e3bc..5e692d86e7 100644 --- a/gentools/src/org/apache/qpid/gentools/LanguageConverter.java +++ b/gentools/src/org/apache/qpid/gentools/LanguageConverter.java @@ -22,18 +22,21 @@ package org.apache.qpid.gentools; public interface LanguageConverter { - public void setDomainMap(AmqpDomainMap domainMap); - public AmqpDomainMap getDomainMap(); - - public void setConstantSet(AmqpConstantSet constantSet); - public AmqpConstantSet getConstantSet(); - - public void setModel(AmqpModel model); - public AmqpModel getModel(); - - public String prepareClassName(String className); - public String prepareMethodName(String methodName); - public String prepareDomainName(String domainName); - public String getDomainType(String domainName, AmqpVersion version) throws AmqpTypeMappingException; - public String getGeneratedType(String domainName, AmqpVersion version) throws AmqpTypeMappingException; + +// public AmqpDomainMap getDomainMap(); +// public AmqpConstantSet getConstantSet(); +// public AmqpModel getModel(); + + // + public String prepareClassName(String className); + + public String prepareMethodName(String methodName); + + public String prepareDomainName(String domainName); + + public String getDomainType(String domainName, AmqpVersion version); + + public String getGeneratedType(String domainName, AmqpVersion version); + + public String prepareConstantName(String constantName); } diff --git a/gentools/src/org/apache/qpid/gentools/Main.java b/gentools/src/org/apache/qpid/gentools/Main.java index e8c8a80a26..c0584f7ca7 100644 --- a/gentools/src/org/apache/qpid/gentools/Main.java +++ b/gentools/src/org/apache/qpid/gentools/Main.java @@ -20,143 +20,149 @@ */ package org.apache.qpid.gentools; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import org.apache.velocity.app.Velocity; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Properties; 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; - private AmqpConstantSet constants; - private AmqpDomainMap domainMap; - private AmqpModel model; - + private static final String DEFAULT_OUTPUT_DIR = ".." + Utils.FILE_SEPARATOR + "gen"; + private static final String DEFAULT_TEMPLATE_DIR_BASE = ".." + Utils.FILE_SEPARATOR; + + private enum GeneratedLanguage + { + CPP(".cpp", CppGenerator.getFactory()), + DOTNET(".net", DotnetGenerator.getFactory()), + JAVA(".java", JavaGenerator.getFactory()); + + private final String _suffix; + private final Generator.Factory _factory; + + + private final String _defaultTemplateDirectory; + + GeneratedLanguage(String suffix, Generator.Factory factory) + { + _suffix = suffix; + _factory = factory; + _defaultTemplateDirectory = DEFAULT_TEMPLATE_DIR_BASE + "templ" + _suffix; + } + + public String getSuffix() + { + return _suffix; + } + + public Generator newGenerator() + { + return _factory.newInstance(); + } + + public String getDefaultTemplateDirectory() + { + return _defaultTemplateDirectory; + } + } + + private Generator generator; + private String outDir; private String tmplDir; - private GeneratorLangEnum generatorLang; + private GeneratedLanguage _generatorLang; private ArrayList<String> xmlFiles; - private File[] modelTemplateFiles; - private File[] classTemplateFiles; - private File[] methodTemplateFiles; - private File[] fieldTemplateFiles; - - public Main() throws ParserConfigurationException - { - docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - versionSet = new AmqpVersionSet(); + + public Main() + { xmlFiles = new ArrayList<String>(); - } - - public void run(String[] args) - throws IOException, - SAXException, - AmqpParseException, - AmqpTypeMappingException, - AmqpTemplateException, - TargetDirectoryException, - IllegalAccessException, - InvocationTargetException - { - modelTemplateFiles = new File[]{}; - classTemplateFiles = new File[]{}; - methodTemplateFiles = new File[]{}; - fieldTemplateFiles = new File[]{}; - + } + + public void run(String[] args) + throws Exception, + SAXException, + AmqpParseException, + AmqpTypeMappingException, + AmqpTemplateException, + TargetDirectoryException, + IllegalAccessException, + InvocationTargetException, ParserConfigurationException + { + // 0. Initialize - outDir = defaultOutDir; + outDir = DEFAULT_OUTPUT_DIR; tmplDir = null; - generatorLang = GeneratorLangEnum.CPP; // Default generation language + _generatorLang = GeneratedLanguage.CPP; // Default generation language xmlFiles.clear(); processArgs(args); - switch (generatorLang) + + if (tmplDir == null) { - case JAVA: - prepareJava(); - break; - case DOTNET: - prepareDotnet(); - break; - default: - prepareCpp(); + tmplDir = _generatorLang.getDefaultTemplateDirectory(); } - if (modelTemplateFiles.length == 0 && classTemplateFiles.length == 0 && - methodTemplateFiles.length == 0 && fieldTemplateFiles.length == 0) - System.err.println(" WARNING: No template files."); - - // 1. Suck in all the XML spec files provided on the command line + + generator = _generatorLang.newGenerator(); + generator.setTemplateDirectory(tmplDir); + generator.setOutputDirectory(outDir); + + // 1. Suck in all the XML spec files provided on the command line analyzeXML(); - - // 2. Load up all templates - try - { - generator.initializeTemplates(modelTemplateFiles, classTemplateFiles, - methodTemplateFiles, fieldTemplateFiles); - } - catch (FileNotFoundException e) - { - System.err.println("Error: Unable to load template file (check -t option on command-line):"); - System.err.println(e.getMessage()); - return; - } - - // 3. Generate output - generator.generate(new File(outDir)); - - System.out.println("Files generated: " + generator.getNumberGeneratedFiles()); - System.out.println("Done."); - } + + Properties p = new Properties(); + p.setProperty("file.resource.loader.path", tmplDir); + + Velocity.init(p); + + // 2. Load up all templates + generator.initializeTemplates(); + + // 3. Generate output + generator.generate(); + + System.out.println("Files generated: " + generator.getNumberGeneratedFiles()); + System.out.println("Done."); + } private void processArgs(String[] args) { // Crude but simple... - for (int i=0; i<args.length; i++) + for (int i = 0; i < args.length; i++) { String arg = args[i]; if (arg.charAt(0) == '-') { switch (arg.charAt(1)) { - case 'c': - case 'C': - generatorLang = GeneratorLangEnum.CPP; + case'c': + case'C': + _generatorLang = GeneratedLanguage.CPP; break; - case 'j': - case 'J': - generatorLang = GeneratorLangEnum.JAVA; + case'j': + case'J': + _generatorLang = GeneratedLanguage.JAVA; break; - case 'n': - case 'N': - generatorLang = GeneratorLangEnum.DOTNET; + case'n': + case'N': + _generatorLang = GeneratedLanguage.DOTNET; break; - case 'o': - case 'O': + case'o': + case'O': if (++i < args.length) { outDir = args[i]; } - break; - case 't': - case 'T': + break; + case't': + case'T': if (++i < args.length) { tmplDir = args[i]; @@ -170,87 +176,12 @@ public class Main } } } - - private void prepareJava() - { - if (tmplDir == null) - tmplDir = defaultJavaTemplateDir; - System.out.println("Java generation mode."); - generator = new JavaGenerator(versionSet); - constants = new AmqpConstantSet(generator); - domainMap = new AmqpDomainMap(generator); - model = new AmqpModel(generator); - modelTemplateFiles = new File[] - { - new File(tmplDir + Utils.fileSeparator + "MethodRegistryClass.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AmqpConstantsClass.tmpl"), - new File(tmplDir + Utils.fileSeparator + "ProtocolVersionListClass.tmpl") - }; - classTemplateFiles = new File[] - { -// new File(tmplDir + Utils.fileSeparator + "PropertyContentHeaderClass.tmpl") - }; - methodTemplateFiles = new File[] - { - new File(tmplDir + Utils.fileSeparator + "MethodBodyClass.tmpl") - }; - } - - 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) - tmplDir = defaultCppTemplateDir; - System.out.println("C++ generation mode."); - generator = new CppGenerator(versionSet); - constants = new AmqpConstantSet(generator); - domainMap = new AmqpDomainMap(generator); - model = new AmqpModel(generator); - modelTemplateFiles = new File[] - { - new File(tmplDir + Utils.fileSeparator + "AMQP_ServerOperations.h.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_ClientOperations.h.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_ServerProxy.h.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_ClientProxy.h.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_ServerProxy.cpp.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_ClientProxy.cpp.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_Constants.h.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_MethodVersionMap.h.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_MethodVersionMap.cpp.tmpl"), - new File(tmplDir + Utils.fileSeparator + "AMQP_HighestVersion.h.tmpl") - }; - methodTemplateFiles = new File[] - { - new File(tmplDir + Utils.fileSeparator + "MethodBodyClass.h.tmpl") - }; - } private void analyzeXML() - throws IOException, SAXException, AmqpParseException, AmqpTypeMappingException + throws IOException, SAXException, AmqpParseException, AmqpTypeMappingException, ParserConfigurationException { + DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + System.out.println("XML files: " + xmlFiles); for (String filename : xmlFiles) { @@ -261,25 +192,21 @@ public class Main System.out.print(" \"" + filename + "\":"); Document doc = docBuilder.parse(new File(filename)); Node amqpNode = Utils.findChild(doc, Utils.ELEMENT_AMQP); - + // 1b. Extract version (major and minor) from the XML file int major = Utils.getNamedIntegerAttribute(amqpNode, Utils.ATTRIBUTE_MAJOR); int minor = Utils.getNamedIntegerAttribute(amqpNode, Utils.ATTRIBUTE_MINOR); AmqpVersion version = new AmqpVersion(major, minor); System.out.println(" Found version " + version.toString() + "."); - versionSet.add(version); - - // 1c. Extract domains - constants.addFromNode(amqpNode, 0, version); - - // 1d. Extract domains - domainMap.addFromNode(amqpNode, 0, version); - - // 1e. Extract class/method/field heirarchy - model.addFromNode(amqpNode, 0, version); + generator.addVersion(version); + generator.addFromNode(amqpNode, version); + + } else + { System.err.println("ERROR: AMQP XML file \"" + filename + "\" not found."); + } } // *** DEBUG INFO *** Uncomment bits from this block to see lots of stuff.... // System.out.println(); @@ -296,58 +223,79 @@ public class Main // System.out.println("*** End debug output ***"); // System.out.println(); } - - public static void main(String[] args) - { - int exitCode = 1; - // TODO: This is a simple and klunky way of hangling command-line args, and could be improved upon. - if (args.length < 2) - { - usage(); - } - else - { - try - { - new Main().run(args); - exitCode = 0; - } - catch (IOException e) { e.printStackTrace(); } - catch (ParserConfigurationException e) { e.printStackTrace(); } - catch (SAXException e) { e.printStackTrace(); } - catch (AmqpParseException e) { e.printStackTrace(); } - catch (AmqpTypeMappingException e) { e.printStackTrace(); } - catch (AmqpTemplateException e) { e.printStackTrace(); } - catch (TargetDirectoryException e) { e.printStackTrace(); } - catch (IllegalAccessException e) { e.printStackTrace(); } - catch (InvocationTargetException e) { e.printStackTrace(); } - } - System.exit(exitCode); - } - - public static void usage() - { - System.out.println("AMQP XML generator v.0.0"); - 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 + "\")."); + + public static void main(String[] args) + { + int exitCode = 1; + // TODO: This is a simple and klunky way of hangling command-line args, and could be improved upon. + if (args.length < 2) + { + usage(); + } + else + { + try + { + new Main().run(args); + exitCode = 0; + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (ParserConfigurationException e) + { + e.printStackTrace(); + } + catch (SAXException e) + { + e.printStackTrace(); + } + catch (AmqpParseException e) + { + e.printStackTrace(); + } + catch (AmqpTypeMappingException e) + { + e.printStackTrace(); + } + catch (AmqpTemplateException e) + { + e.printStackTrace(); + } + catch (TargetDirectoryException e) + { + e.printStackTrace(); + } + catch (IllegalAccessException e) + { + e.printStackTrace(); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + System.exit(exitCode); + } + + public static void usage() + { + System.out.println("AMQP XML generator v.0.0"); + 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=\"" + DEFAULT_OUTPUT_DIR + "\")."); System.out.println(" -t tmplDir: Find templates in tmplDir."); - System.out.println(" Defaults: \"" + defaultCppTemplateDir + "\" for C++;"); - System.out.println(" \"" + defaultJavaTemplateDir + "\" for java."); - System.out.println(" XMLfile is a space-separated list of AMQP XML files to be parsed."); - } - - public static String ListTemplateList(File[] list) - { - StringBuffer sb = new StringBuffer(); - for (int i=0; i<list.length; i++) - { - if (i != 0) - sb.append(", "); - sb.append(list[i].getName()); - } - return sb.toString(); - } + System.out.println(" Defaults: \"" + GeneratedLanguage.CPP.getDefaultTemplateDirectory() + "\" for C++;"); + System.out.println(" \"" + GeneratedLanguage.JAVA.getDefaultTemplateDirectory() + "\" for java.;"); + System.out.println(" \"" + GeneratedLanguage.DOTNET.getDefaultTemplateDirectory() + "\" for .NET."); + System.out.println(" XMLfile is a space-separated list of AMQP XML files to be parsed."); + } + } diff --git a/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java b/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java new file mode 100644 index 0000000000..73706ec7a5 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java @@ -0,0 +1,26 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+public interface MangledGenerateMethod
+{
+ String generate(AmqpField field, int indentSize, int tabSize, boolean notLast);
+}
diff --git a/gentools/src/org/apache/qpid/gentools/NodeAware.java b/gentools/src/org/apache/qpid/gentools/NodeAware.java index df4e0ecb02..f832da75ad 100644 --- a/gentools/src/org/apache/qpid/gentools/NodeAware.java +++ b/gentools/src/org/apache/qpid/gentools/NodeAware.java @@ -24,23 +24,24 @@ import org.w3c.dom.Node; /** * @author kpvdr - * Interface allowing the addition of elements from a node in the - * DOM of the AMQP specification. It is used by each of the model - * elements in a recursive fashion to build the model. + * Interface allowing the addition of elements from a node in the + * DOM of the AMQP specification. It is used by each of the model + * elements in a recursive fashion to build the model. */ public interface NodeAware { - /** - * Add a model element from the current DOM node. All model elements must implement - * this interface. If the node contains children that are also a part of the model, - * then this method is called on new instances of those model elements. - * @param n Node from which the current model element is to be added. - * @param o Ordinal value of the current model elemet. - * @param v Verion of the DOM from which the node comes. - * @throws AmqpParseException - * @throws AmqpTypeMappingException - * @returns true if a node was added, false if not - */ - public boolean addFromNode(Node n, int o, AmqpVersion v) - throws AmqpParseException, AmqpTypeMappingException; + /** + * Add a model element from the current DOM node. All model elements must implement + * this interface. If the node contains children that are also a part of the model, + * then this method is called on new instances of those model elements. + * + * @param n Node from which the current model element is to be added. + * @param o Ordinal value of the current model elemet. + * @param v Verion of the DOM from which the node comes. + * @throws AmqpParseException + * @throws AmqpTypeMappingException + * @returns true if a node was added, false if not + */ + public boolean addFromNode(Node n, int o, AmqpVersion v) + throws AmqpParseException, AmqpTypeMappingException; } diff --git a/gentools/src/org/apache/qpid/gentools/Printable.java b/gentools/src/org/apache/qpid/gentools/Printable.java index a73878c506..aa13df7b68 100644 --- a/gentools/src/org/apache/qpid/gentools/Printable.java +++ b/gentools/src/org/apache/qpid/gentools/Printable.java @@ -24,5 +24,5 @@ import java.io.PrintStream; public interface Printable { - public void print(PrintStream out, int marginSize, int tabSize); + public void print(PrintStream out, int marginSize, int tabSize); } diff --git a/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java b/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java new file mode 100644 index 0000000000..152d6c5fc2 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java @@ -0,0 +1,103 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Map.Entry;
+
+
+public class SingleVersionClass
+{
+ private final int _classId;
+
+
+ private final AmqpClass _amqpClass;
+ private final AmqpVersion _amqpVersion;
+ private final Generator _generator;
+ private final List<SingleVersionMethod> _methodList = new ArrayList<SingleVersionMethod>();
+
+ public SingleVersionClass(AmqpClass amqpClass, AmqpVersion amqpVersion, Generator generator)
+ {
+ _amqpClass = amqpClass;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+
+ AmqpOrdinalVersionMap indexMap = amqpClass.getIndexMap();
+ int classId = 0;
+ for(Entry<Integer, AmqpVersionSet> entry : indexMap.entrySet())
+ {
+ if(entry.getValue().contains(_amqpVersion))
+ {
+ classId = entry.getKey();
+ break;
+ }
+ }
+ _classId = classId;
+
+
+ Collection<AmqpMethod> methods = _amqpClass.getMethodMap().values();
+
+ for(AmqpMethod amqpMethod : methods)
+ {
+ _methodList.add(new SingleVersionMethod(amqpMethod, _amqpVersion, _generator));
+
+ }
+
+ Collections.sort(_methodList, new Comparator<SingleVersionMethod>(){
+ public int compare(SingleVersionMethod method1, SingleVersionMethod method2)
+ {
+ return method1.getMethodId() - method2.getMethodId();
+ }
+ });
+
+
+ }
+
+ public int getClassId()
+ {
+ return _classId;
+ }
+
+ public String getName()
+ {
+ return _amqpClass.getName();
+ }
+
+
+
+
+
+ public List<SingleVersionMethod> getMethodList()
+ {
+ return _methodList;
+ }
+
+
+ public int getMaximumMethodId()
+ {
+ return _methodList.get(_methodList.size()-1).getMethodId();
+ }
+}
diff --git a/gentools/src/org/apache/qpid/gentools/SingleVersionField.java b/gentools/src/org/apache/qpid/gentools/SingleVersionField.java new file mode 100644 index 0000000000..84586fc31c --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/SingleVersionField.java @@ -0,0 +1,68 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+
+public class SingleVersionField
+{
+ private final AmqpField _field;
+ private final AmqpVersion _amqpVersion;
+ private final Generator _generator;
+
+ public SingleVersionField(AmqpField field, AmqpVersion amqpVersion, Generator generator)
+ {
+ _field = field;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+ }
+
+ public String getName()
+ {
+ return _field.getName();
+ }
+
+ public String getDomain()
+ {
+ return _field.getDomain(_amqpVersion);
+ }
+
+
+ public String getDomainType()
+ {
+ return _generator.getDomainType(_field.getDomain(_amqpVersion),_amqpVersion);
+ }
+
+ public String getNativeType()
+ {
+ return _generator.getNativeType(getDomainType());
+ }
+
+ public String getEncodingType()
+ {
+ return _generator.getEncodingType(getDomainType());
+ }
+
+
+ public int getPosition()
+ {
+ return _field.getOrdinal(_amqpVersion);
+ }
+}
diff --git a/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java b/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java new file mode 100644 index 0000000000..d69bf46e01 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java @@ -0,0 +1,154 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+import java.util.Map.Entry;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+
+public class SingleVersionMethod
+{
+ private final AmqpMethod _amqpMethod;
+ private final AmqpVersion _amqpVersion;
+ private final int _methodId;
+ private final List<SingleVersionField> _fieldList = new ArrayList<SingleVersionField>();
+ private final Generator _generator;
+ private final List<ConsolidatedField> _consolidatedFields = new ArrayList<ConsolidatedField>();
+ private final Map<String, ConsolidatedField> _fieldNameToConsolidatedFieldMap = new HashMap<String, ConsolidatedField>();
+
+
+ public SingleVersionMethod(AmqpMethod amqpMethod, AmqpVersion amqpVersion, Generator generator)
+ {
+ _amqpMethod = amqpMethod;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+
+ AmqpOrdinalVersionMap indexMap = amqpMethod.getIndexMap();
+ int methodId = 0;
+ for(Entry<Integer, AmqpVersionSet> entry : indexMap.entrySet())
+ {
+ if(entry.getValue().contains(_amqpVersion))
+ {
+ methodId = entry.getKey();
+ break;
+ }
+ }
+ _methodId = methodId;
+
+ Collection<AmqpField> fields = _amqpMethod.getFieldMap().values();
+
+ for(AmqpField field : fields)
+ {
+ _fieldList.add(new SingleVersionField(field, _amqpVersion, _generator));
+
+ }
+
+ Collections.sort(_fieldList, new Comparator<SingleVersionField>(){
+ public int compare(SingleVersionField field1, SingleVersionField field2)
+ {
+ return field1.getPosition() - field2.getPosition();
+ }
+ });
+
+
+
+ ConsolidatedField lastField = null;
+ int bitfieldNum = 0;
+ for(SingleVersionField field : _fieldList)
+ {
+ String domainType = field.getDomainType();
+ if(!domainType.equals("bit"))
+ {
+ lastField = new ConsolidatedField(_generator,
+ field.getName(),
+ field.getDomainType());
+ _consolidatedFields.add(lastField);
+ }
+ else if(lastField == null || !lastField.getType().equals("bitfield"))
+ {
+ lastField = new ConsolidatedField(_generator,
+ domainType.equals("bit") ? "bitfield"+bitfieldNum++ : field.getName(),
+ domainType.equals("bit") ? "bitfield" : field.getDomainType(),
+ field.getName());
+ _consolidatedFields.add(lastField);
+ }
+ else
+ {
+ lastField.add(field.getName());
+ }
+ _fieldNameToConsolidatedFieldMap.put(field.getName(), lastField);
+
+ }
+ }
+
+ public int getMethodId()
+ {
+ return _methodId;
+ }
+
+ public String getName()
+ {
+ return _amqpMethod.getName();
+ }
+
+ public Collection<SingleVersionField> getFieldList()
+ {
+ return Collections.unmodifiableCollection(_fieldList);
+ }
+
+ public List<ConsolidatedField> getConsolidatedFields()
+ {
+ return _consolidatedFields;
+ }
+
+ public String getConsolidatedFieldName(String fieldName)
+ {
+ return _fieldNameToConsolidatedFieldMap.get(fieldName).getName();
+ }
+
+ public boolean isConsolidated(String fieldName)
+ {
+ return _fieldNameToConsolidatedFieldMap.get(fieldName).isConsolidated();
+ }
+
+ public int getPositionInBitField(String fieldName)
+ {
+ return _fieldNameToConsolidatedFieldMap.get(fieldName).getPosition(fieldName);
+ }
+
+
+ public boolean isServerMethod()
+ {
+ return _amqpMethod.isServerMethod(_amqpVersion);
+ }
+
+
+ public boolean isClientMethod()
+ {
+ return _amqpMethod.isClientMethod(_amqpVersion);
+ }
+
+}
diff --git a/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java b/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java new file mode 100644 index 0000000000..31d7275647 --- /dev/null +++ b/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java @@ -0,0 +1,71 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.gentools;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+
+public class SingleVersionModel
+{
+ private final AmqpModel _amqpModel;
+ private final AmqpVersion _amqpVersion;
+ private final Generator _generator;
+ private final List<SingleVersionClass> _classList = new ArrayList<SingleVersionClass>();
+
+ public SingleVersionModel(AmqpModel amqpModel, AmqpVersion amqpVersion, Generator generator)
+ {
+ _amqpModel = amqpModel;
+ _amqpVersion = amqpVersion;
+ _generator = generator;
+
+
+ Collection<AmqpClass> originalClasses = _amqpModel.getClassMap().values();
+
+ for(AmqpClass amqpClass : originalClasses)
+ {
+ _classList.add(new SingleVersionClass(amqpClass, _amqpVersion, _generator));
+
+ }
+
+ Collections.sort(_classList, new Comparator<SingleVersionClass>(){
+ public int compare(SingleVersionClass amqpClass1, SingleVersionClass amqpClass2)
+ {
+ return amqpClass1.getClassId() - amqpClass2.getClassId();
+ }
+ });
+
+
+ }
+
+ public Collection<SingleVersionClass> getClassList()
+ {
+ return Collections.unmodifiableCollection(_classList);
+ }
+
+ public int getMaximumClassId()
+ {
+ return _classList.get(_classList.size()-1).getClassId();
+ }
+}
diff --git a/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java b/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java index cdaf381f0a..39ce666288 100644 --- a/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java +++ b/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class TargetDirectoryException extends Exception +public class TargetDirectoryException extends RuntimeException { - public TargetDirectoryException(String msg) - { - super(msg); - } + public TargetDirectoryException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/Utils.java b/gentools/src/org/apache/qpid/gentools/Utils.java index ade00cd8c7..1cedaeea12 100644 --- a/gentools/src/org/apache/qpid/gentools/Utils.java +++ b/gentools/src/org/apache/qpid/gentools/Utils.java @@ -21,103 +21,114 @@ package org.apache.qpid.gentools; import org.w3c.dom.Attr; -//import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Utils { - public final static String fileSeparator = System.getProperty("file.separator"); - public final static String lineSeparator = System.getProperty("line.separator"); - - public final static String ATTRIBUTE_NAME = "name"; - public final static String ATTRIBUTE_MAJOR = "major"; - public final static String ATTRIBUTE_MINOR = "minor"; - public final static String ATTRIBUTE_INDEX = "index"; - public final static String ATTRIBUTE_LABEL = "label"; - public final static String ATTRIBUTE_SYNCHRONOUS = "synchronous"; - public final static String ATTRIBUTE_CONTENT = "content"; - public final static String ATTRIBUTE_HANDLER = "handler"; - public final static String ATTRIBUTE_DOMAIN = "domain"; + public final static String FILE_SEPARATOR = System.getProperty("file.separator"); + public final static String LINE_SEPARATOR = System.getProperty("line.separator"); + + public final static String ATTRIBUTE_NAME = "name"; + public final static String ATTRIBUTE_MAJOR = "major"; + public final static String ATTRIBUTE_MINOR = "minor"; + public final static String ATTRIBUTE_INDEX = "index"; + public final static String ATTRIBUTE_LABEL = "label"; + public final static String ATTRIBUTE_SYNCHRONOUS = "synchronous"; + public final static String ATTRIBUTE_CONTENT = "content"; + public final static String ATTRIBUTE_HANDLER = "handler"; + public final static String ATTRIBUTE_DOMAIN = "domain"; public final static String ATTRIBUTE_VALUE = "value"; - public final static String ATTRIBUTE_TYPE = "type"; // For compatibility with AMQP 8.0 - - public final static String ELEMENT_AMQP = "amqp"; - public final static String ELEMENT_CHASSIS = "chassis"; - public final static String ELEMENT_CLASS = "class"; - public final static String ELEMENT_CODEGEN = "codegen"; + public final static String ATTRIBUTE_TYPE = "type"; // For compatibility with AMQP 8.0 + + public final static String ELEMENT_AMQP = "amqp"; + public final static String ELEMENT_CHASSIS = "chassis"; + public final static String ELEMENT_CLASS = "class"; + public final static String ELEMENT_CODEGEN = "codegen"; public final static String ELEMENT_CONSTANT = "constant"; - public final static String ELEMENT_DOMAIN = "domain"; - public final static String ELEMENT_METHOD = "method"; - public final static String ELEMENT_FIELD = "field"; - public final static String ELEMENT_VERSION = "version"; - - // Attribute functions - - public static String getNamedAttribute(Node n, String attrName) throws AmqpParseException - { - NamedNodeMap nnm = n.getAttributes(); - if (nnm == null) - throw new AmqpParseException("Node \"" + n.getNodeName() + "\" has no attributes."); - Attr a = (Attr)nnm.getNamedItem(attrName); - if (a == null) - throw new AmqpParseException("Node \"" + n.getNodeName() + "\" has no attribute \"" + attrName + "\"."); - return a.getNodeValue(); - } - - public static int getNamedIntegerAttribute(Node n, String attrName) throws AmqpParseException - { - return Integer.parseInt(getNamedAttribute(n, attrName)); - } - - // Element functions - - public static Node findChild(Node n, String eltName) throws AmqpParseException - { - NodeList nl = n.getChildNodes(); - for (int i=0; i<nl.getLength(); i++) - { - Node cn = nl.item(i); - if (cn.getNodeName().compareTo(eltName) == 0) - return cn; - } - throw new AmqpParseException("Node \"" + n.getNodeName() + - "\" does not contain child element \"" + eltName + "\"."); - } - - // String functions - - public static String firstUpper(String str) - { - if (!Character.isLowerCase(str.charAt(0))) - return str; - StringBuffer sb = new StringBuffer(str); - sb.setCharAt(0, Character.toUpperCase(str.charAt(0))); - return sb.toString(); - } - - public static String firstLower(String str) - { - if (!Character.isUpperCase(str.charAt(0))) - return str; - StringBuffer sb = new StringBuffer(str); - sb.setCharAt(0, Character.toLowerCase(str.charAt(0))); - return sb.toString(); - } - - public static String createSpaces(int cnt) - { - StringBuffer sb = new StringBuffer(); - for (int i=0; i<cnt; i++) - sb.append(' '); - return sb.toString(); - } - + public final static String ELEMENT_DOMAIN = "domain"; + public final static String ELEMENT_METHOD = "method"; + public final static String ELEMENT_FIELD = "field"; + public final static String ELEMENT_VERSION = "version"; + + // Attribute functions + + public static String getNamedAttribute(Node n, String attrName) throws AmqpParseException + { + NamedNodeMap nnm = n.getAttributes(); + if (nnm == null) + { + throw new AmqpParseException("Node \"" + n.getNodeName() + "\" has no attributes."); + } + Attr a = (Attr) nnm.getNamedItem(attrName); + if (a == null) + { + throw new AmqpParseException("Node \"" + n.getNodeName() + "\" has no attribute \"" + attrName + "\"."); + } + return a.getNodeValue(); + } + + public static int getNamedIntegerAttribute(Node n, String attrName) throws AmqpParseException + { + return Integer.parseInt(getNamedAttribute(n, attrName)); + } + + // Element functions + + public static Node findChild(Node n, String eltName) throws AmqpParseException + { + NodeList nl = n.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) + { + Node cn = nl.item(i); + if (cn.getNodeName().compareTo(eltName) == 0) + { + return cn; + } + } + throw new AmqpParseException("Node \"" + n.getNodeName() + + "\" does not contain child element \"" + eltName + "\"."); + } + + // String functions + + public static String firstUpper(String str) + { + if (!Character.isLetter(str.charAt(0)) || !Character.isLowerCase(str.charAt(0))) + { + return str; + } + StringBuffer sb = new StringBuffer(str); + sb.setCharAt(0, Character.toUpperCase(str.charAt(0))); + return sb.toString(); + } + + public static String firstLower(String str) + { + if (!Character.isUpperCase(str.charAt(0))) + { + return str; + } + StringBuffer sb = new StringBuffer(str); + sb.setCharAt(0, Character.toLowerCase(str.charAt(0))); + return sb.toString(); + } + + public static String createSpaces(int cnt) + { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < cnt; i++) + { + sb.append(' '); + } + return sb.toString(); + } + public static boolean containsOnlyDigits(String str) { boolean foundNonDigit = false; - for (int i=0; i<str.length() && !foundNonDigit; i++) + for (int i = 0; i < str.length() && !foundNonDigit; i++) { if (!Character.isDigit(str.charAt(i))) { @@ -126,12 +137,12 @@ public class Utils } return !foundNonDigit; } - + public static boolean containsOnlyDigitsAndDecimal(String str) { boolean foundNonDigit = false; int decimalCntr = 0; - for (int i=0; i<str.length() && !foundNonDigit && decimalCntr<2; i++) + for (int i = 0; i < str.length() && !foundNonDigit && decimalCntr < 2; i++) { char ch = str.charAt(i); if (!(Character.isDigit(ch) || ch == '.')) @@ -139,8 +150,10 @@ public class Utils foundNonDigit = true; } else if (ch == '.') + { decimalCntr++; + } } - return !foundNonDigit && decimalCntr<2; + return !foundNonDigit && decimalCntr < 2; } } diff --git a/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java b/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java index 1f6b9f1a6d..a9cdd56e88 100644 --- a/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java +++ b/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java @@ -22,5 +22,5 @@ package org.apache.qpid.gentools; public interface VersionConsistencyCheck { - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet); + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index 17300d6b50..0907ea9df0 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -266,8 +266,8 @@ public class AMQChannel // returns true iff the message was delivered (i.e. if all data was // received if (_currentMessage.addContentBodyFrame(_storeContext, - protocolSession.getRegistry().getProtocolVersionMethodConverter().convertToContentChunk( - contentBody))) + protocolSession.getMethodRegistry().getProtocolVersionMethodConverter().convertToContentChunk( + contentBody))) { // callback to allow the context to do any post message processing // primary use is to allow message return processing in the non-tx case diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java new file mode 100644 index 0000000000..6ace626c28 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/AccessRequestHandler.java @@ -0,0 +1,44 @@ +package org.apache.qpid.server.handler;
+
+import org.apache.qpid.framing.*;
+import org.apache.qpid.server.state.StateAwareMethodListener;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.AMQException;
+
+/**
+ * @author Apache Software Foundation
+ *
+ *
+ */
+public class AccessRequestHandler implements StateAwareMethodListener<AccessRequestBody>
+{
+ private static final AccessRequestHandler _instance = new AccessRequestHandler();
+
+
+ public static AccessRequestHandler getInstance()
+ {
+ return _instance;
+ }
+
+ private AccessRequestHandler()
+ {
+ }
+
+ public void methodReceived(AMQStateManager stateManager, AccessRequestBody body, int channelId) throws AMQException
+ {
+ AMQProtocolSession session = stateManager.getProtocolSession();
+
+ MethodRegistry methodRegistry = session.getMethodRegistry();
+
+ // We don't implement access control class, but to keep clients happy that expect it
+ // always use the "0" ticket.
+ AccessRequestOkBody response = methodRegistry.createAccessRequestOkBody(0);
+
+ session.writeFrame(response.generateFrame(channelId));
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java index a6972475a6..f90e7c3dff 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java @@ -44,24 +44,24 @@ public class BasicAckMethodHandler implements StateAwareMethodListener<BasicAckB { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicAckBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicAckBody body, int channelId) throws AMQException { AMQProtocolSession protocolSession = stateManager.getProtocolSession(); - BasicAckBody body = evt.getMethod(); + if (_log.isDebugEnabled()) { - _log.debug("Ack(Tag:" + body.deliveryTag + ":Mult:" + body.multiple + ") received on channel " + evt.getChannelId()); + _log.debug("Ack(Tag:" + body.getDeliveryTag() + ":Mult:" + body.getMultiple() + ") received on channel " + channelId); } - final AMQChannel channel = protocolSession.getChannel(evt.getChannelId()); + final AMQChannel channel = protocolSession.getChannel(channelId); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } // this method throws an AMQException if the delivery tag is not known - channel.acknowledgeMessage(body.deliveryTag, body.multiple); + channel.acknowledgeMessage(body.getDeliveryTag(), body.getMultiple()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java index 8bab96a11b..bda1c16cf6 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicCancelMethodHandler.java @@ -24,6 +24,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.BasicCancelBody; import org.apache.qpid.framing.BasicCancelOkBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -46,34 +47,30 @@ public class BasicCancelMethodHandler implements StateAwareMethodListener<BasicC { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicCancelBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicCancelBody body, int channelId) throws AMQException { - AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + AMQProtocolSession session = stateManager.getProtocolSession(); + + final AMQChannel channel = session.getChannel(channelId); - final AMQChannel channel = protocolSession.getChannel(evt.getChannelId()); - final BasicCancelBody body = evt.getMethod(); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } if (_log.isDebugEnabled()) { - _log.debug("BasicCancel: for:" + body.consumerTag + - " nowait:" + body.nowait); + _log.debug("BasicCancel: for:" + body.getConsumerTag() + + " nowait:" + body.getNowait()); } - channel.unsubscribeConsumer(protocolSession, body.consumerTag); - if (!body.nowait) + channel.unsubscribeConsumer(session, body.getConsumerTag()); + if (!body.getNowait()) { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame responseFrame = BasicCancelOkBody.createAMQFrame(evt.getChannelId(), - (byte) 8, (byte) 0, // AMQP version (major, minor) - body.consumerTag); // consumerTag - protocolSession.writeFrame(responseFrame); + MethodRegistry methodRegistry = session.getMethodRegistry(); + BasicCancelOkBody cancelOkBody = methodRegistry.createBasicCancelOkBody(body.getConsumerTag()); + session.writeFrame(cancelOkBody.generateFrame(channelId)); } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java index d1e4ae6aa6..bb48539f50 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java @@ -22,11 +22,7 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicConsumeBody; -import org.apache.qpid.framing.BasicConsumeOkBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; @@ -52,12 +48,12 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicConsumeBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicConsumeBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - BasicConsumeBody body = evt.getMethod(); - final int channelId = evt.getChannelId(); + + AMQChannel channel = session.getChannel(channelId); @@ -65,29 +61,29 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } else { if (_log.isDebugEnabled()) { - _log.debug("BasicConsume: from '" + body.queue + - "' for:" + body.consumerTag + - " nowait:" + body.nowait + - " args:" + body.arguments); + _log.debug("BasicConsume: from '" + body.getQueue() + + "' for:" + body.getConsumerTag() + + " nowait:" + body.getNowait() + + " args:" + body.getArguments()); } - AMQQueue queue = body.queue == null ? channel.getDefaultQueue() : vHost.getQueueRegistry().getQueue(body.queue); + AMQQueue queue = body.getQueue() == null ? channel.getDefaultQueue() : vHost.getQueueRegistry().getQueue(body.getQueue().intern()); if (queue == null) { if (_log.isTraceEnabled()) { - _log.trace("No queue for '" + body.queue + "'"); + _log.trace("No queue for '" + body.getQueue() + "'"); } - if (body.queue != null) + if (body.getQueue() != null) { - String msg = "No such queue, '" + body.queue + "'"; + String msg = "No such queue, '" + body.getQueue() + "'"; throw body.getChannelException(AMQConstant.NOT_FOUND, msg); } else @@ -99,23 +95,27 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic else { - if (body.consumerTag != null) + final AMQShortString consumerTagName; + + if (body.getConsumerTag() != null) + { + consumerTagName = body.getConsumerTag().intern(); + } + else { - body.consumerTag = body.consumerTag.intern(); + consumerTagName = null; } try { - AMQShortString consumerTag = channel.subscribeToQueue(body.consumerTag, queue, session, !body.noAck, - body.arguments, body.noLocal, body.exclusive); - if (!body.nowait) + AMQShortString consumerTag = channel.subscribeToQueue(consumerTagName, queue, session, !body.getNoAck(), + body.getArguments(), body.getNoLocal(), body.getExclusive()); + if (!body.getNowait()) { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(BasicConsumeOkBody.createAMQFrame(channelId, - (byte) 8, (byte) 0, // AMQP version (major, minor) - consumerTag)); // consumerTag + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createBasicConsumeOkBody(consumerTag); + session.writeFrame(responseBody.generateFrame(channelId)); + } //now allow queue to start async processing of any backlog of messages @@ -124,33 +124,26 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic catch (org.apache.qpid.AMQInvalidArgumentException ise) { _log.debug("Closing connection due to invalid selector"); - // Why doesn't this ChannelException work. -// throw body.getChannelException(AMQConstant.INVALID_ARGUMENT, ise.getMessage()); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(ChannelCloseBody.createAMQFrame(channelId, - (byte) 8, (byte) 0, // AMQP version (major, minor) - BasicConsumeBody.getClazz((byte) 8, (byte) 0), // classId - BasicConsumeBody.getMethod((byte) 8, (byte) 0), // methodId - AMQConstant.INVALID_ARGUMENT.getCode(), // replyCode - new AMQShortString(ise.getMessage()))); // replyText + + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createChannelCloseBody(AMQConstant.INVALID_ARGUMENT.getCode(), + new AMQShortString(ise.getMessage()), + body.getClazz(), + body.getMethod()); + session.writeFrame(responseBody.generateFrame(channelId)); + + } catch (ConsumerTagNotUniqueException e) { - AMQShortString msg = new AMQShortString("Non-unique consumer tag, '" + body.consumerTag + "'"); - // If the above doesn't work then perhaps this is wrong too. -// throw body.getConnectionException(AMQConstant.NOT_ALLOWED, -// "Non-unique consumer tag, '" + body.consumerTag + "'"); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(ConnectionCloseBody.createAMQFrame(channelId, - (byte) 8, (byte) 0, // AMQP version (major, minor) - BasicConsumeBody.getClazz((byte) 8, (byte) 0), // classId - BasicConsumeBody.getMethod((byte) 8, (byte) 0), // methodId - AMQConstant.NOT_ALLOWED.getCode(), // replyCode - msg)); // replyText + AMQShortString msg = new AMQShortString("Non-unique consumer tag, '" + body.getConsumerTag() + "'"); + + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createConnectionCloseBody(AMQConstant.NOT_ALLOWED.getCode(), // replyCode + msg, // replytext + body.getClazz(), + body.getMethod()); + session.writeFrame(responseBody.generateFrame(0)); } catch (AMQQueue.ExistingExclusiveSubscription e) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java index 782a89c704..8d69697350 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java @@ -25,6 +25,7 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException;
import org.apache.qpid.framing.BasicGetBody;
import org.apache.qpid.framing.BasicGetEmptyBody;
+import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.server.AMQChannel;
@@ -49,30 +50,29 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB {
}
- public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicGetBody> evt) throws AMQException
+ public void methodReceived(AMQStateManager stateManager, BasicGetBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
- BasicGetBody body = evt.getMethod();
- final int channelId = evt.getChannelId();
+
VirtualHost vHost = session.getVirtualHost();
AMQChannel channel = session.getChannel(channelId);
if (channel == null)
{
- throw body.getChannelNotFoundException(evt.getChannelId());
+ throw body.getChannelNotFoundException(channelId);
}
else
{
- AMQQueue queue = body.queue == null ? channel.getDefaultQueue() : vHost.getQueueRegistry().getQueue(body.queue);
+ AMQQueue queue = body.getQueue() == null ? channel.getDefaultQueue() : vHost.getQueueRegistry().getQueue(body.getQueue());
if (queue == null)
{
- _log.info("No queue for '" + body.queue + "'");
- if(body.queue!=null)
+ _log.info("No queue for '" + body.getQueue() + "'");
+ if(body.getQueue()!=null)
{
throw body.getConnectionException(AMQConstant.NOT_FOUND,
- "No such queue, '" + body.queue + "'");
+ "No such queue, '" + body.getQueue()+ "'");
}
else
{
@@ -82,12 +82,14 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB }
else
{
- if(!queue.performGet(session, channel, !body.noAck))
+ if(!queue.performGet(session, channel, !body.getNoAck()))
{
+ MethodRegistry methodRegistry = session.getMethodRegistry();
+ // TODO - set clusterId
+ BasicGetEmptyBody responseBody = methodRegistry.createBasicGetEmptyBody(null);
- // TODO - set clusterId
- session.writeFrame(BasicGetEmptyBody.createAMQFrame(channelId, body.getMajor(), body.getMinor(), null));
+ session.writeFrame(responseBody.generateFrame(channelId));
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java index 68d4483df3..66afc61751 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java @@ -24,6 +24,8 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.exchange.ExchangeDefaults; import org.apache.qpid.framing.BasicPublishBody; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; @@ -50,29 +52,27 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicPublishBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicPublishBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - final BasicPublishBody body = evt.getMethod(); + if (_log.isDebugEnabled()) { - _log.debug("Publish received on channel " + evt.getChannelId()); + _log.debug("Publish received on channel " + channelId); } + AMQShortString exchange = body.getExchange(); // TODO: check the delivery tag field details - is it unique across the broker or per subscriber? - if (body.exchange == null) + if (exchange == null) { - body.exchange = ExchangeDefaults.DEFAULT_EXCHANGE_NAME; + exchange = ExchangeDefaults.DEFAULT_EXCHANGE_NAME; } - else - { - body.exchange = body.exchange.intern(); - } + VirtualHost vHost = session.getVirtualHost(); - Exchange e = vHost.getExchangeRegistry().getExchange(body.exchange); + Exchange e = vHost.getExchangeRegistry().getExchange(exchange); // if the exchange does not exist we raise a channel exception if (e == null) { @@ -83,22 +83,18 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basi // The partially populated BasicDeliver frame plus the received route body // is stored in the channel. Once the final body frame has been received // it is routed to the exchange. - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } - if(body.routingKey != null) - { - body.routingKey = body.routingKey.intern(); - } - - MessagePublishInfo info = session.getRegistry().getProtocolVersionMethodConverter().convertToInfo(body); + MessagePublishInfo info = session.getMethodRegistry().getProtocolVersionMethodConverter().convertToInfo(body); channel.setPublishFrame(info, session); } } + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java index 3cd6a87f64..3c95180dca 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicQosHandler.java @@ -23,6 +23,8 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicQosBody; import org.apache.qpid.framing.BasicQosOkBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; @@ -38,21 +40,21 @@ public class BasicQosHandler implements StateAwareMethodListener<BasicQosBody> return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicQosBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicQosBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw evt.getMethod().getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } - channel.setPrefetchCount(evt.getMethod().prefetchCount); - channel.setPrefetchSize(evt.getMethod().prefetchSize); + channel.setPrefetchCount(body.getPrefetchCount()); + channel.setPrefetchSize(body.getPrefetchSize()); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(BasicQosOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0)); + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createBasicQosOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java index a436c35473..c7842cd643 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java @@ -24,6 +24,9 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.BasicRecoverBody; import org.apache.qpid.framing.BasicRecoverOkBody; +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -41,24 +44,30 @@ public class BasicRecoverMethodHandler implements StateAwareMethodListener<Basic return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicRecoverBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicRecoverBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - _logger.debug("Recover received on protocol session " + session + " and channel " + evt.getChannelId()); - AMQChannel channel = session.getChannel(evt.getChannelId()); - BasicRecoverBody body = evt.getMethod(); + _logger.debug("Recover received on protocol session " + session + " and channel " + channelId); + AMQChannel channel = session.getChannel(channelId); + if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } - channel.resend(body.requeue); + channel.resend(body.getRequeue()); + + // Qpid 0-8 hacks a synchronous -ok onto recover. + // In Qpid 0-9 we create a separate sync-recover, sync-recover-ok pair to be "more" compliant + if(session.getProtocolVersion().equals(ProtocolVersion.v8_0)) + { + MethodRegistry_8_0 methodRegistry = (MethodRegistry_8_0) session.getMethodRegistry(); + AMQMethodBody recoverOk = methodRegistry.createBasicRecoverOkBody(); + session.writeFrame(recoverOk.generateFrame(channelId)); + + } - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(BasicRecoverOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java new file mode 100644 index 0000000000..15484273c8 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverSyncMethodHandler.java @@ -0,0 +1,54 @@ +package org.apache.qpid.server.handler;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.framing.BasicRecoverBody;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.BasicRecoverSyncBody;
+import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9;
+import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0;
+import org.apache.qpid.server.state.StateAwareMethodListener;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.AMQException;
+
+public class BasicRecoverSyncMethodHandler implements StateAwareMethodListener<BasicRecoverSyncBody>
+{
+ private static final Logger _logger = Logger.getLogger(BasicRecoverSyncMethodHandler.class);
+
+ private static final BasicRecoverSyncMethodHandler _instance = new BasicRecoverSyncMethodHandler();
+
+ public static BasicRecoverSyncMethodHandler getInstance()
+ {
+ return _instance;
+ }
+
+ public void methodReceived(AMQStateManager stateManager, BasicRecoverSyncBody body, int channelId) throws AMQException
+ {
+ AMQProtocolSession session = stateManager.getProtocolSession();
+
+ _logger.debug("Recover received on protocol session " + session + " and channel " + channelId);
+ AMQChannel channel = session.getChannel(channelId);
+
+
+ if (channel == null)
+ {
+ throw body.getChannelNotFoundException(channelId);
+ }
+
+ channel.resend(body.getRequeue());
+
+ // Qpid 0-8 hacks a synchronous -ok onto recover.
+ // In Qpid 0-9 we create a separate sync-recover, sync-recover-ok pair to be "more" compliant
+ if(session.getProtocolVersion().equals(ProtocolVersion.v0_9))
+ {
+ MethodRegistry_0_9 methodRegistry = (MethodRegistry_0_9) session.getMethodRegistry();
+ AMQMethodBody recoverOk = methodRegistry.createBasicRecoverSyncOkBody();
+ session.writeFrame(recoverOk.generateFrame(channelId));
+
+ }
+
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java index aca485f62a..4f3aee0c93 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRejectMethodHandler.java @@ -45,11 +45,11 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<BasicRejectBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, BasicRejectBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - int channelId = evt.getChannelId(); + // if (_logger.isDebugEnabled()) // { @@ -63,18 +63,18 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR if (channel == null) { - throw evt.getMethod().getChannelNotFoundException(channelId); + throw body.getChannelNotFoundException(channelId); } if (_logger.isDebugEnabled()) { - _logger.debug("Rejecting:" + evt.getMethod().deliveryTag + - ": Requeue:" + evt.getMethod().requeue + + _logger.debug("Rejecting:" + body.getDeliveryTag() + + ": Requeue:" + body.getRequeue() + //": Resend:" + evt.getMethod().resend + " on channel:" + channel.debugIdentity()); } - long deliveryTag = evt.getMethod().deliveryTag; + long deliveryTag = body.getDeliveryTag(); UnacknowledgedMessage message = channel.getUnacknowledgedMessageMap().get(deliveryTag); @@ -103,7 +103,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR if (_logger.isTraceEnabled()) { _logger.trace("Rejecting: DT:" + deliveryTag + "-" + message.message.debugIdentity() + - ": Requeue:" + evt.getMethod().requeue + + ": Requeue:" + body.getRequeue() + //": Resend:" + evt.getMethod().resend + " on channel:" + channel.debugIdentity()); } @@ -114,7 +114,7 @@ public class BasicRejectMethodHandler implements StateAwareMethodListener<BasicR message.message.reject(message.message.getDeliveredSubscription(message.queue)); } - if (evt.getMethod().requeue) + if (body.getRequeue()) { channel.requeue(deliveryTag); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java index 1f4f1f9221..9133cce6b7 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseHandler.java @@ -25,6 +25,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.ChannelCloseBody; import org.apache.qpid.framing.ChannelCloseOkBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -47,16 +48,16 @@ public class ChannelCloseHandler implements StateAwareMethodListener<ChannelClos { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ChannelCloseBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ChannelCloseBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - ChannelCloseBody body = evt.getMethod(); + if (_logger.isInfoEnabled()) { - _logger.info("Received channel close for id " + evt.getChannelId() + " citing class " + body.classId + - " and method " + body.methodId); + _logger.info("Received channel close for id " + channelId + " citing class " + body.getClassId() + + " and method " + body.getMethodId()); } - int channelId = evt.getChannelId(); + AMQChannel channel = session.getChannel(channelId); @@ -69,10 +70,8 @@ public class ChannelCloseHandler implements StateAwareMethodListener<ChannelClos // Client requested closure so we don't wait for ok we send it stateManager.getProtocolSession().closeChannelOk(channelId); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = ChannelCloseOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0); - session.writeFrame(response); + MethodRegistry methodRegistry = session.getMethodRegistry(); + ChannelCloseOkBody responseBody = methodRegistry.createChannelCloseOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java index ad5604e7ea..a857490e7e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelCloseOkHandler.java @@ -42,9 +42,9 @@ public class ChannelCloseOkHandler implements StateAwareMethodListener<ChannelCl { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ChannelCloseOkBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ChannelCloseOkBody body, int channelId) throws AMQException { - int channelId = evt.getChannelId(); + _logger.info("Received channel-close-ok for channel-id " + channelId); // Let the Protocol Session know the channel is now closed. diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java index bfa170cfc5..696ca8a63b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelFlowHandler.java @@ -22,9 +22,7 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ChannelFlowBody; -import org.apache.qpid.framing.ChannelFlowOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -46,27 +44,23 @@ public class ChannelFlowHandler implements StateAwareMethodListener<ChannelFlowB { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ChannelFlowBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ChannelFlowBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - ChannelFlowBody body = evt.getMethod(); - AMQChannel channel = session.getChannel(evt.getChannelId()); + + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } - channel.setSuspended(!body.active); - _logger.debug("Channel.Flow for channel " + evt.getChannelId() + ", active=" + body.active); + channel.setSuspended(!body.getActive()); + _logger.debug("Channel.Flow for channel " + channelId + ", active=" + body.getActive()); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = ChannelFlowOkBody.createAMQFrame(evt.getChannelId(), - (byte)8, (byte)0, // AMQP version (major, minor) - body.active); // active - session.writeFrame(response); + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createChannelFlowOkBody(body.getActive()); + session.writeFrame(responseBody.generateFrame(channelId)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java index 03fc7a3926..3f604480b9 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java @@ -20,11 +20,17 @@ */ package org.apache.qpid.server.handler; +import java.util.UUID; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; + import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ChannelOpenBody; -import org.apache.qpid.framing.ChannelOpenOkBody; +import org.apache.qpid.framing.*; +import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9; +import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0; import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; @@ -44,18 +50,55 @@ public class ChannelOpenHandler implements StateAwareMethodListener<ChannelOpenB { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ChannelOpenBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ChannelOpenBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); VirtualHost virtualHost = session.getVirtualHost(); - final AMQChannel channel = new AMQChannel(session,evt.getChannelId(), virtualHost.getMessageStore(), + final AMQChannel channel = new AMQChannel(session,channelId, virtualHost.getMessageStore(), virtualHost.getExchangeRegistry()); session.addChannel(channel); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = ChannelOpenOkBody.createAMQFrame(evt.getChannelId(), (byte)8, (byte)0); - session.writeFrame(response); + + ChannelOpenOkBody response; + + ProtocolVersion pv = session.getProtocolVersion(); + + if(pv.equals(ProtocolVersion.v8_0)) + { + MethodRegistry_8_0 methodRegistry = (MethodRegistry_8_0) MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0); + response = methodRegistry.createChannelOpenOkBody(); + + } + else if(pv.equals(ProtocolVersion.v0_9)) + { + MethodRegistry_0_9 methodRegistry = (MethodRegistry_0_9) MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9); + UUID uuid = UUID.randomUUID(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + DataOutputStream dataOut = new DataOutputStream(output); + try + { + dataOut.writeLong(uuid.getMostSignificantBits()); + dataOut.writeLong(uuid.getLeastSignificantBits()); + dataOut.flush(); + dataOut.close(); + } + catch (IOException e) + { + // This *really* shouldn't happen as we're not doing any I/O + throw new RuntimeException("I/O exception when writing to byte array", e); + } + + // should really associate this channelId to the session + byte[] channelName = output.toByteArray(); + + response = methodRegistry.createChannelOpenOkBody(channelName); + } + else + { + throw new AMQException(AMQConstant.INTERNAL_ERROR, "Got channel open for protocol version not catered for: " + pv, null); + } + + + session.writeFrame(response.generateFrame(channelId)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java index b086cad67f..dade5d5f54 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseMethodHandler.java @@ -25,6 +25,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.ConnectionCloseOkBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; @@ -45,14 +46,14 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ConnectionCloseBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionCloseBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - final ConnectionCloseBody body = evt.getMethod(); + if (_logger.isInfoEnabled()) { - _logger.info("ConnectionClose received with reply code/reply text " + body.replyCode + "/" + - body.replyText + " for " + session); + _logger.info("ConnectionClose received with reply code/reply text " + body.getReplyCode() + "/" + + body.getReplyText() + " for " + session); } try { @@ -62,10 +63,10 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener<Co { _logger.error("Error closing protocol session: " + e, e); } - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame response = ConnectionCloseOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0); - session.writeFrame(response); + + MethodRegistry methodRegistry = session.getMethodRegistry(); + ConnectionCloseOkBody responseBody = methodRegistry.createConnectionCloseOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java index 853f4df435..bc6e5ab403 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionCloseOkMethodHandler.java @@ -44,7 +44,7 @@ public class ConnectionCloseOkMethodHandler implements StateAwareMethodListener< { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ConnectionCloseOkBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionCloseOkBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); //todo should this not do more than just log the method? diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java index 30a40c5a75..4f62e0b930 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java @@ -21,10 +21,7 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionOpenBody; -import org.apache.qpid.framing.ConnectionOpenOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -56,20 +53,20 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con return new AMQShortString(Long.toString(System.currentTimeMillis())); } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ConnectionOpenBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionOpenBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - ConnectionOpenBody body = evt.getMethod(); + //ignore leading '/' String virtualHostName; - if ((body.virtualHost != null) && body.virtualHost.charAt(0) == '/') + if ((body.getVirtualHost() != null) && body.getVirtualHost().charAt(0) == '/') { - virtualHostName = new StringBuilder(body.virtualHost.subSequence(1, body.virtualHost.length())).toString(); + virtualHostName = new StringBuilder(body.getVirtualHost().subSequence(1, body.getVirtualHost().length())).toString(); } else { - virtualHostName = body.virtualHost == null ? null : String.valueOf(body.virtualHost); + virtualHostName = body.getVirtualHost() == null ? null : String.valueOf(body.getVirtualHost()); } VirtualHost virtualHost = stateManager.getVirtualHostRegistry().getVirtualHost(virtualHostName); @@ -105,14 +102,14 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con session.setContextKey(generateClientID()); } - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = ConnectionOpenOkBody.createAMQFrame((short) 0, - (byte) 8, (byte) 0, // AMQP version (major, minor) - body.virtualHost); + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createConnectionOpenOkBody(body.getVirtualHost()); + stateManager.changeState(AMQState.CONNECTION_OPEN); - session.writeFrame(response); + + session.writeFrame(responseBody.generateFrame(channelId)); + + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java index fef00942a0..193c3a088b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java @@ -25,11 +25,7 @@ import javax.security.sasl.SaslServer; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionSecureBody; -import org.apache.qpid.framing.ConnectionSecureOkBody; -import org.apache.qpid.framing.ConnectionTuneBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -57,10 +53,10 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ConnectionSecureOkBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionSecureOkBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - ConnectionSecureOkBody body = evt.getMethod(); + //fixme Vhost not defined yet //session.getVirtualHost().getAuthenticationManager(); @@ -71,8 +67,8 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener { throw new AMQException("No SASL context set up in session"); } - - AuthenticationResult authResult = authMgr.authenticate(ss, body.response); + MethodRegistry methodRegistry = session.getMethodRegistry(); + AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); switch (authResult.status) { case ERROR: @@ -80,45 +76,34 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener // throw new AMQException(AMQConstant.NOT_ALLOWED.getCode(), AMQConstant.NOT_ALLOWED.getName()); _logger.info("Authentication failed"); stateManager.changeState(AMQState.CONNECTION_CLOSING); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame close = ConnectionCloseBody.createAMQFrame(0, - (byte)8, (byte)0, // AMQP version (major, minor) - ConnectionCloseBody.getClazz((byte)8, (byte)0), // classId - ConnectionCloseBody.getMethod((byte)8, (byte)0), // methodId - AMQConstant.NOT_ALLOWED.getCode(), // replyCode - AMQConstant.NOT_ALLOWED.getName()); // replyText - session.writeFrame(close); + + + ConnectionCloseBody connectionCloseBody = + methodRegistry.createConnectionCloseBody(AMQConstant.NOT_ALLOWED.getCode(), + AMQConstant.NOT_ALLOWED.getName(), + body.getClazz(), + body.getMethod()); + + session.writeFrame(connectionCloseBody.generateFrame(0) ); disposeSaslServer(session); break; case SUCCESS: _logger.info("Connected as: " + ss.getAuthorizationID()); stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - // TODO: Check the value of channelMax here: This should be the max - // value of a 2-byte unsigned integer (as channel is only 2 bytes on the wire), - // not Integer.MAX_VALUE (which is signed 4 bytes). - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame tune = ConnectionTuneBody.createAMQFrame(0, - (byte)8, (byte)0, // AMQP version (major, minor) - Integer.MAX_VALUE, // channelMax - ConnectionStartOkMethodHandler.getConfiguredFrameSize(), // frameMax - HeartbeatConfig.getInstance().getDelay()); // heartbeat - session.writeFrame(tune); + + ConnectionTuneBody tuneBody = + methodRegistry.createConnectionTuneBody(0xFFFF, + ConnectionStartOkMethodHandler.getConfiguredFrameSize(), + HeartbeatConfig.getInstance().getDelay()); + session.writeFrame(tuneBody.generateFrame(0)); session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID())); disposeSaslServer(session); break; case CONTINUE: stateManager.changeState(AMQState.CONNECTION_NOT_AUTH); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame challenge = ConnectionSecureBody.createAMQFrame(0, - (byte)8, (byte)0, // AMQP version (major, minor) - authResult.challenge); // challenge - session.writeFrame(challenge); + + ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge); + session.writeFrame(secureBody.generateFrame(0)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java index bb9eeed1d4..f02121c89f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java @@ -26,11 +26,7 @@ import javax.security.sasl.SaslServer; import org.apache.commons.configuration.Configuration; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ConnectionSecureBody; -import org.apache.qpid.framing.ConnectionStartOkBody; -import org.apache.qpid.framing.ConnectionTuneBody; -import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -53,7 +49,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< private static final int DEFAULT_FRAME_SIZE = 65536; - public static StateAwareMethodListener<ConnectionStartOkBody> getInstance() + public static ConnectionStartOkMethodHandler getInstance() { return _instance; } @@ -62,51 +58,51 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ConnectionStartOkBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionStartOkBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - final ConnectionStartOkBody body = evt.getMethod(); - _logger.info("SASL Mechanism selected: " + body.mechanism); - _logger.info("Locale selected: " + body.locale); + + _logger.info("SASL Mechanism selected: " + body.getMechanism()); + _logger.info("Locale selected: " + body.getLocale()); AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();//session.getVirtualHost().getAuthenticationManager(); SaslServer ss = null; try { - ss = authMgr.createSaslServer(String.valueOf(body.mechanism), session.getLocalFQDN()); + ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN()); if (ss == null) { - throw body.getConnectionException(AMQConstant.RESOURCE_ERROR, "Unable to create SASL Server:" + body.mechanism + throw body.getConnectionException(AMQConstant.RESOURCE_ERROR, "Unable to create SASL Server:" + body.getMechanism() ); } session.setSaslServer(ss); - AuthenticationResult authResult = authMgr.authenticate(ss, body.response); + AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); //save clientProperties if (session.getClientProperties() == null) { - session.setClientProperties(body.clientProperties); + session.setClientProperties(body.getClientProperties()); } + MethodRegistry methodRegistry = session.getMethodRegistry(); + switch (authResult.status) { case ERROR: _logger.info("Authentication failed"); stateManager.changeState(AMQState.CONNECTION_CLOSING); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame close = ConnectionCloseBody.createAMQFrame(0, - (byte) 8, (byte) 0, // AMQP version (major, minor) - ConnectionCloseBody.getClazz((byte) 8, (byte) 0), // classId - ConnectionCloseBody.getMethod((byte) 8, (byte) 0), // methodId - AMQConstant.NOT_ALLOWED.getCode(), // replyCode - AMQConstant.NOT_ALLOWED.getName()); // replyText - session.writeFrame(close); + + ConnectionCloseBody closeBody = + methodRegistry.createConnectionCloseBody(AMQConstant.NOT_ALLOWED.getCode(), // replyCode + AMQConstant.NOT_ALLOWED.getName(), + body.getClazz(), + body.getMethod()); + + session.writeFrame(closeBody.generateFrame(0)); disposeSaslServer(session); break; @@ -115,25 +111,17 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID())); stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame tune = ConnectionTuneBody.createAMQFrame(0, - (byte) 8, (byte) 0, // AMQP version (major, minor) - Integer.MAX_VALUE, // channelMax - getConfiguredFrameSize(), // frameMax - HeartbeatConfig.getInstance().getDelay()); // heartbeat - session.writeFrame(tune); + + ConnectionTuneBody tuneBody = methodRegistry.createConnectionTuneBody(0xFFFF, + getConfiguredFrameSize(), + HeartbeatConfig.getInstance().getDelay()); + session.writeFrame(tuneBody.generateFrame(0)); break; case CONTINUE: stateManager.changeState(AMQState.CONNECTION_NOT_AUTH); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame challenge = ConnectionSecureBody.createAMQFrame(0, - (byte) 8, (byte) 0, // AMQP version (major, minor) - authResult.challenge); // challenge - session.writeFrame(challenge); + + ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge); + session.writeFrame(secureBody.generateFrame(0)); } } catch (SaslException e) diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java index ab7695955c..0fe8c5dc92 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java @@ -40,15 +40,15 @@ public class ConnectionTuneOkMethodHandler implements StateAwareMethodListener<C return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ConnectionTuneOkBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionTuneOkBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - ConnectionTuneOkBody body = evt.getMethod(); + if (_logger.isDebugEnabled()) { _logger.debug(body); } stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); - session.initHeartbeats(body.heartbeat); + session.initHeartbeats(body.getHeartbeat()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java index 162c03b025..491a2f80db 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeBoundHandler.java @@ -21,10 +21,8 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ExchangeBoundBody; -import org.apache.qpid.framing.ExchangeBoundOkBody; +import org.apache.qpid.framing.*; +import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.exchange.Exchange; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -36,6 +34,8 @@ import org.apache.qpid.server.virtualhost.VirtualHost; /** * @author Apache Software Foundation + * + * */ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBoundBody> { @@ -64,35 +64,32 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ExchangeBoundBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ExchangeBoundBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); + VirtualHost virtualHost = session.getVirtualHost(); QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); + MethodRegistry methodRegistry = session.getMethodRegistry(); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - byte major = (byte)8; - byte minor = (byte)0; - ExchangeBoundBody body = evt.getMethod(); - AMQShortString exchangeName = body.exchange; - AMQShortString queueName = body.queue; - AMQShortString routingKey = body.routingKey; + + AMQShortString exchangeName = body.getExchange(); + AMQShortString queueName = body.getQueue(); + AMQShortString routingKey = body.getRoutingKey(); if (exchangeName == null) { throw new AMQException("Exchange exchange must not be null"); } Exchange exchange = virtualHost.getExchangeRegistry().getExchange(exchangeName); - AMQFrame response; + ExchangeBoundOkBody response; if (exchange == null) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - EXCHANGE_NOT_FOUND, // replyCode - new AMQShortString("Exchange " + exchangeName + " not found")); // replyText + + + response = methodRegistry.createExchangeBoundOkBody(EXCHANGE_NOT_FOUND, + new AMQShortString("Exchange " + exchangeName + " not found")); } else if (routingKey == null) { @@ -100,18 +97,12 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo { if (exchange.hasBindings()) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - OK, // replyCode - null); // replyText + response = methodRegistry.createExchangeBoundOkBody(OK, null); } else { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - NO_BINDINGS, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(NO_BINDINGS, // replyCode null); // replyText } } @@ -121,28 +112,22 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo AMQQueue queue = queueRegistry.getQueue(queueName); if (queue == null) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - QUEUE_NOT_FOUND, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(QUEUE_NOT_FOUND, // replyCode new AMQShortString("Queue " + queueName + " not found")); // replyText } else { if (exchange.isBound(queue)) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - OK, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(OK, // replyCode null); // replyText } else { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - QUEUE_NOT_BOUND, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(QUEUE_NOT_BOUND, // replyCode new AMQShortString("Queue " + queueName + " not bound to exchange " + exchangeName)); // replyText } } @@ -153,53 +138,43 @@ public class ExchangeBoundHandler implements StateAwareMethodListener<ExchangeBo AMQQueue queue = queueRegistry.getQueue(queueName); if (queue == null) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - QUEUE_NOT_FOUND, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(QUEUE_NOT_FOUND, // replyCode new AMQShortString("Queue " + queueName + " not found")); // replyText } else { - if (exchange.isBound(body.routingKey, queue)) + if (exchange.isBound(body.getRoutingKey(), queue)) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - OK, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(OK, // replyCode null); // replyText } else { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - SPECIFIC_QUEUE_NOT_BOUND_WITH_RK, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(SPECIFIC_QUEUE_NOT_BOUND_WITH_RK, // replyCode new AMQShortString("Queue " + queueName + " not bound with routing key " + - body.routingKey + " to exchange " + exchangeName)); // replyText + body.getRoutingKey() + " to exchange " + exchangeName)); // replyText } } } else { - if (exchange.isBound(body.routingKey)) + if (exchange.isBound(body.getRoutingKey())) { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - OK, // replyCode + + response = methodRegistry.createExchangeBoundOkBody(OK, // replyCode null); // replyText } else { - // AMQP version change: Be aware of possible changes to parameter order as versions change. - response = ExchangeBoundOkBody.createAMQFrame(evt.getChannelId(), - major, minor, // AMQP version (major, minor) - NO_QUEUE_BOUND_WITH_RK, // replyCode - new AMQShortString("No queue bound with routing key " + body.routingKey + + + response = methodRegistry.createExchangeBoundOkBody(NO_QUEUE_BOUND_WITH_RK, // replyCode + new AMQShortString("No queue bound with routing key " + body.getRoutingKey() + " to exchange " + exchangeName)); // replyText } } - session.writeFrame(response); + session.writeFrame(response.generateFrame(channelId)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java index 8ab8366d9e..c4a57f0286 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java @@ -24,9 +24,7 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQConnectionException; import org.apache.qpid.AMQException; import org.apache.qpid.AMQUnknownExchangeType; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeclareOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.exchange.Exchange; @@ -54,61 +52,60 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ExchangeDeclareBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ExchangeDeclareBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); VirtualHost virtualHost = session.getVirtualHost(); ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry(); ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory(); - final ExchangeDeclareBody body = evt.getMethod(); + if (_logger.isDebugEnabled()) { - _logger.debug("Request to declare exchange of type " + body.type + " with name " + body.exchange); + _logger.debug("Request to declare exchange of type " + body.getType() + " with name " + body.getExchange()); } synchronized(exchangeRegistry) { - Exchange exchange = exchangeRegistry.getExchange(body.exchange); + Exchange exchange = exchangeRegistry.getExchange(body.getExchange()); if (exchange == null) { - if(body.passive && ((body.type == null) || body.type.length() ==0)) + if(body.getPassive() && ((body.getType() == null) || body.getType().length() ==0)) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Unknown exchange: " + body.exchange); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Unknown exchange: " + body.getExchange()); } else { try { - exchange = exchangeFactory.createExchange(body.exchange == null ? null : body.exchange.intern(), - body.type == null ? null : body.type.intern(), - body.durable, - body.passive, body.ticket); + exchange = exchangeFactory.createExchange(body.getExchange() == null ? null : body.getExchange().intern(), + body.getType() == null ? null : body.getType().intern(), + body.getDurable(), + body.getPassive(), body.getTicket()); exchangeRegistry.registerExchange(exchange); } catch(AMQUnknownExchangeType e) { - throw body.getConnectionException(AMQConstant.COMMAND_INVALID, "Unknown exchange: " + body.exchange,e); + throw body.getConnectionException(AMQConstant.COMMAND_INVALID, "Unknown exchange: " + body.getExchange(),e); } } } - else if (!exchange.getType().equals(body.type)) + else if (!exchange.getType().equals(body.getType())) { - throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.exchange + " of type " + exchange.getType() + " to " + body.type +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor()); + throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getType() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor()); } } - if(!body.nowait) + if(!body.getNowait()) { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = ExchangeDeclareOkBody.createAMQFrame(evt.getChannelId(), (byte)8, (byte)0); - session.writeFrame(response); + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createExchangeDeclareOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java index f9926c399c..8f36e6c767 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java @@ -45,21 +45,20 @@ public class ExchangeDeleteHandler implements StateAwareMethodListener<ExchangeD { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<ExchangeDeleteBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ExchangeDeleteBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); VirtualHost virtualHost = session.getVirtualHost(); ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry(); - ExchangeDeleteBody body = evt.getMethod(); + try { - exchangeRegistry.unregisterExchange(body.exchange, body.ifUnused); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = ExchangeDeleteOkBody.createAMQFrame(evt.getChannelId(), (byte)8, (byte)0); - session.writeFrame(response); + exchangeRegistry.unregisterExchange(body.getExchange(), body.getIfUnused()); + + ExchangeDeleteOkBody responseBody = session.getMethodRegistry().createExchangeDeleteOkBody(); + + session.writeFrame(responseBody.generateFrame(channelId)); } catch (ExchangeInUseException e) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java index 3e68069838..057586a143 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java @@ -23,9 +23,7 @@ package org.apache.qpid.server.handler; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.AMQInvalidRoutingKeyException; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.QueueBindBody; -import org.apache.qpid.framing.QueueBindOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; @@ -53,22 +51,24 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody> { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<QueueBindBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, QueueBindBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); VirtualHost virtualHost = session.getVirtualHost(); ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry(); QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); - final QueueBindBody body = evt.getMethod(); + final AMQQueue queue; - if (body.queue == null) + final AMQShortString routingKey; + + if (body.getQueue() == null) { - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } queue = channel.getDefaultQueue(); @@ -78,41 +78,42 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody> throw body.getChannelException(AMQConstant.NOT_FOUND, "No default queue defined on channel and queue was null"); } - if (body.routingKey == null) + if (body.getRoutingKey() == null) + { + routingKey = queue.getName(); + } + else { - body.routingKey = queue.getName(); + routingKey = body.getRoutingKey().intern(); } } else { - queue = queueRegistry.getQueue(body.queue); + queue = queueRegistry.getQueue(body.getQueue()); + routingKey = body.getRoutingKey() == null ? null : body.getRoutingKey().intern(); } if (queue == null) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.queue + " does not exist."); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.getQueue() + " does not exist."); } - final Exchange exch = exchangeRegistry.getExchange(body.exchange); + final Exchange exch = exchangeRegistry.getExchange(body.getExchange()); if (exch == null) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.exchange + " does not exist."); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.getExchange() + " does not exist."); } - if (body.routingKey != null) - { - body.routingKey = body.routingKey.intern(); - } try { - if (!exch.isBound(body.routingKey, body.arguments, queue)) + if (!exch.isBound(routingKey, body.getArguments(), queue)) { - queue.bind(body.routingKey, body.arguments, exch); + queue.bind(routingKey, body.getArguments(), exch); } } catch (AMQInvalidRoutingKeyException rke) { - throw body.getChannelException(AMQConstant.INVALID_ROUTING_KEY, body.routingKey.toString()); + throw body.getChannelException(AMQConstant.INVALID_ROUTING_KEY, routingKey.toString()); } catch (AMQException e) { @@ -121,15 +122,14 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody> if (_log.isInfoEnabled()) { - _log.info("Binding queue " + queue + " to exchange " + exch + " with routing key " + body.routingKey); + _log.info("Binding queue " + queue + " to exchange " + exch + " with routing key " + routingKey); } - if (!body.nowait) + if (!body.getNowait()) { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame response = QueueBindOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0); - session.writeFrame(response); + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createQueueBindOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); + } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index 29697542be..f59fcf2a12 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -28,10 +28,7 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.configuration.Configured; import org.apache.qpid.exchange.ExchangeDefaults; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.QueueDeclareBody; -import org.apache.qpid.framing.QueueDeclareOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.configuration.Configurator; @@ -70,7 +67,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar Configurator.configure(this); } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<QueueDeclareBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, QueueDeclareBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); VirtualHost virtualHost = session.getVirtualHost(); @@ -78,12 +75,20 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); MessageStore store = virtualHost.getMessageStore(); - QueueDeclareBody body = evt.getMethod(); + + + + final AMQShortString queueName; // if we aren't given a queue name, we create one which we return to the client - if (body.queue == null) + + if (body.getQueue() == null) { - body.queue = createName(); + queueName = createName(); + } + else + { + queueName = body.getQueue().intern(); } AMQQueue queue; @@ -94,16 +99,12 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar - if (((queue = queueRegistry.getQueue(body.queue)) == null)) + if (((queue = queueRegistry.getQueue(queueName)) == null)) { - if(body.queue != null) - { - body.queue = body.queue.intern(); - } - if (body.passive) + if (body.getPassive()) { - String msg = "Queue: " + body.queue + " not found on VirtualHost(" + virtualHost + ")."; + String msg = "Queue: " + queueName + " not found on VirtualHost(" + virtualHost + ")."; throw body.getChannelException(AMQConstant.NOT_FOUND, msg); } else @@ -118,42 +119,40 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar { Exchange defaultExchange = exchangeRegistry.getDefaultExchange(); - queue.bind(body.queue, null, defaultExchange); - _log.info("Queue " + body.queue + " bound to default exchange(" + defaultExchange.getName() + ")"); + queue.bind(queueName, null, defaultExchange); + _log.info("Queue " + queueName + " bound to default exchange(" + defaultExchange.getName() + ")"); } } } else if (queue.getOwner() != null && !session.getContextKey().equals(queue.getOwner())) { - throw body.getChannelException(AMQConstant.ALREADY_EXISTS, "Cannot declare queue('" + body.queue + "')," + throw body.getChannelException(AMQConstant.ALREADY_EXISTS, "Cannot declare queue('" + queueName + "')," + " as exclusive queue with same name " + "declared on another client ID('" + queue.getOwner() + "')"); } - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } //set this as the default queue on the channel: channel.setDefaultQueue(queue); } - if (!body.nowait) + if (!body.getNowait()) { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame response = QueueDeclareOkBody.createAMQFrame(evt.getChannelId(), - (byte) 8, (byte) 0, // AMQP version (major, minor) - queue.getConsumerCount(), // consumerCount - queue.getMessageCount(), // messageCount - body.queue); // queue - _log.info("Queue " + body.queue + " declared successfully"); - session.writeFrame(response); + MethodRegistry methodRegistry = session.getMethodRegistry(); + QueueDeclareOkBody responseBody = + methodRegistry.createQueueDeclareOkBody(queueName, + queue.getMessageCount(), + queue.getConsumerCount()); + session.writeFrame(responseBody.generateFrame(channelId)); + + _log.info("Queue " + queueName + " declared successfully"); } } @@ -166,11 +165,11 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar throws AMQException { final QueueRegistry registry = virtualHost.getQueueRegistry(); - AMQShortString owner = body.exclusive ? session.getContextKey() : null; - final AMQQueue queue = new AMQQueue(body.queue, body.durable, owner, body.autoDelete, virtualHost); + AMQShortString owner = body.getExclusive() ? session.getContextKey() : null; + final AMQQueue queue = new AMQQueue(body.getQueue(), body.getDurable(), owner, body.getAutoDelete(), virtualHost); final AMQShortString queueName = queue.getName(); - if (body.exclusive && !body.durable) + if (body.getExclusive() && !body.getDurable()) { final AMQProtocolSession.Task deleteQueueTask = new AMQProtocolSession.Task() diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java index eb7089afdc..09b7de3a5c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; import org.apache.qpid.framing.QueueDeleteBody; import org.apache.qpid.framing.QueueDeleteOkBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -56,22 +57,21 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<QueueDeleteBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, QueueDeleteBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); VirtualHost virtualHost = session.getVirtualHost(); QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); MessageStore store = virtualHost.getMessageStore(); - QueueDeleteBody body = evt.getMethod(); AMQQueue queue; - if (body.queue == null) + if (body.getQueue() == null) { - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw body.getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } //get the default queue on the channel: @@ -79,43 +79,40 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB } else { - queue = queueRegistry.getQueue(body.queue); + queue = queueRegistry.getQueue(body.getQueue()); } if (queue == null) { if (_failIfNotFound) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.queue + " does not exist."); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.getQueue() + " does not exist."); } } else { - if (body.ifEmpty && !queue.isEmpty()) + if (body.getIfEmpty() && !queue.isEmpty()) { - throw body.getChannelException(AMQConstant.IN_USE, "Queue: " + body.queue + " is not empty."); + throw body.getChannelException(AMQConstant.IN_USE, "Queue: " + body.getQueue() + " is not empty."); } - else if (body.ifUnused && !queue.isUnused()) + else if (body.getIfUnused() && !queue.isUnused()) { // TODO - Error code - throw body.getChannelException(AMQConstant.IN_USE, "Queue: " + body.queue + " is still used."); + throw body.getChannelException(AMQConstant.IN_USE, "Queue: " + body.getQueue() + " is still used."); } else { - int purged = queue.delete(body.ifUnused, body.ifEmpty); + int purged = queue.delete(body.getIfUnused(), body.getIfEmpty()); if (queue.isDurable()) { store.removeQueue(queue.getName()); } - - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(QueueDeleteOkBody.createAMQFrame(evt.getChannelId(), - (byte) 8, (byte) 0, // AMQP version (major, minor) - purged)); // messageCount + + MethodRegistry methodRegistry = session.getMethodRegistry(); + QueueDeleteOkBody responseBody = methodRegistry.createQueueDeleteOkBody(purged); + session.writeFrame(responseBody.generateFrame(channelId)); } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java index 3e1937bb43..5bdca93bc6 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java @@ -24,6 +24,8 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException;
import org.apache.qpid.framing.QueuePurgeBody;
import org.apache.qpid.framing.QueuePurgeOkBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.server.protocol.AMQProtocolSession;
@@ -55,22 +57,22 @@ public class QueuePurgeHandler implements StateAwareMethodListener<QueuePurgeBod _failIfNotFound = failIfNotFound;
}
- public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<QueuePurgeBody> evt) throws AMQException
+ public void methodReceived(AMQStateManager stateManager, QueuePurgeBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
VirtualHost virtualHost = session.getVirtualHost();
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
- AMQChannel channel = session.getChannel(evt.getChannelId());
+ AMQChannel channel = session.getChannel(channelId);
+
- QueuePurgeBody body = evt.getMethod();
AMQQueue queue;
- if(body.queue == null)
+ if(body.getQueue() == null)
{
if (channel == null)
{
- throw body.getChannelNotFoundException(evt.getChannelId());
+ throw body.getChannelNotFoundException(channelId);
}
//get the default queue on the channel:
@@ -86,14 +88,14 @@ public class QueuePurgeHandler implements StateAwareMethodListener<QueuePurgeBod }
else
{
- queue = queueRegistry.getQueue(body.queue);
+ queue = queueRegistry.getQueue(body.getQueue());
}
if(queue == null)
{
if(_failIfNotFound)
{
- throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.queue + " does not exist.");
+ throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.getQueue() + " does not exist.");
}
}
else
@@ -101,14 +103,13 @@ public class QueuePurgeHandler implements StateAwareMethodListener<QueuePurgeBod long purged = queue.clearQueue(channel.getStoreContext());
- if(!body.nowait)
+ if(!body.getNowait())
{
- // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
- // TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
- // Be aware of possible changes to parameter order as versions change.
- session.writeFrame(QueuePurgeOkBody.createAMQFrame(evt.getChannelId(),
- (byte)8, (byte)0, // AMQP version (major, minor)
- purged)); // messageCount
+
+ MethodRegistry methodRegistry = session.getMethodRegistry();
+ AMQMethodBody responseBody = methodRegistry.createQueuePurgeOkBody(purged);
+ session.writeFrame(responseBody.generateFrame(channelId));
+
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java new file mode 100644 index 0000000000..9475b83c8f --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl.java @@ -0,0 +1,566 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.handler;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.AMQException;
+
+public class ServerMethodDispatcherImpl implements MethodDispatcher
+{
+ private final AMQStateManager _stateManager;
+
+ private static interface DispatcherFactory
+ {
+ public MethodDispatcher createMethodDispatcher(AMQStateManager stateManager);
+ }
+
+ private static final Map<ProtocolVersion, DispatcherFactory> _dispatcherFactories =
+ new HashMap<ProtocolVersion, DispatcherFactory>();
+
+
+ static
+ {
+ _dispatcherFactories.put(ProtocolVersion.v8_0,
+ new DispatcherFactory()
+ {
+ public MethodDispatcher createMethodDispatcher(AMQStateManager stateManager)
+ {
+ return new ServerMethodDispatcherImpl_8_0(stateManager);
+ }
+ });
+
+ _dispatcherFactories.put(ProtocolVersion.v0_9,
+ new DispatcherFactory()
+ {
+ public MethodDispatcher createMethodDispatcher(AMQStateManager stateManager)
+ {
+ return new ServerMethodDispatcherImpl_0_9(stateManager);
+ }
+ });
+
+ }
+
+
+ private static final AccessRequestHandler _accessRequestHandler = AccessRequestHandler.getInstance();
+ private static final ChannelCloseHandler _channelCloseHandler = ChannelCloseHandler.getInstance();
+ private static final ChannelOpenHandler _channelOpenHandler = ChannelOpenHandler.getInstance();
+ private static final ChannelCloseOkHandler _channelCloseOkHandler = ChannelCloseOkHandler.getInstance();
+ private static final ConnectionCloseMethodHandler _connectionCloseMethodHandler = ConnectionCloseMethodHandler.getInstance();
+ private static final ConnectionCloseOkMethodHandler _connectionCloseOkMethodHandler = ConnectionCloseOkMethodHandler.getInstance();
+ private static final ConnectionOpenMethodHandler _connectionOpenMethodHandler = ConnectionOpenMethodHandler.getInstance();
+ private static final ConnectionTuneOkMethodHandler _connectionTuneOkMethodHandler = ConnectionTuneOkMethodHandler.getInstance();
+ private static final ConnectionSecureOkMethodHandler _connectionSecureOkMethodHandler = ConnectionSecureOkMethodHandler.getInstance();
+ private static final ConnectionStartOkMethodHandler _connectionStartOkMethodHandler = ConnectionStartOkMethodHandler.getInstance();
+ private static final ExchangeDeclareHandler _exchangeDeclareHandler = ExchangeDeclareHandler.getInstance();
+ private static final ExchangeDeleteHandler _exchangeDeleteHandler = ExchangeDeleteHandler.getInstance();
+ private static final ExchangeBoundHandler _exchangeBoundHandler = ExchangeBoundHandler.getInstance();
+ private static final BasicAckMethodHandler _basicAckMethodHandler = BasicAckMethodHandler.getInstance();
+ private static final BasicRecoverMethodHandler _basicRecoverMethodHandler = BasicRecoverMethodHandler.getInstance();
+ private static final BasicConsumeMethodHandler _basicConsumeMethodHandler = BasicConsumeMethodHandler.getInstance();
+ private static final BasicGetMethodHandler _basicGetMethodHandler = BasicGetMethodHandler.getInstance();
+ private static final BasicCancelMethodHandler _basicCancelMethodHandler = BasicCancelMethodHandler.getInstance();
+ private static final BasicPublishMethodHandler _basicPublishMethodHandler = BasicPublishMethodHandler.getInstance();
+ private static final BasicQosHandler _basicQosHandler = BasicQosHandler.getInstance();
+ private static final QueueBindHandler _queueBindHandler = QueueBindHandler.getInstance();
+ private static final QueueDeclareHandler _queueDeclareHandler = QueueDeclareHandler.getInstance();
+ private static final QueueDeleteHandler _queueDeleteHandler = QueueDeleteHandler.getInstance();
+ private static final QueuePurgeHandler _queuePurgeHandler = QueuePurgeHandler.getInstance();
+ private static final ChannelFlowHandler _channelFlowHandler = ChannelFlowHandler.getInstance();
+ private static final TxSelectHandler _txSelectHandler = TxSelectHandler.getInstance();
+ private static final TxCommitHandler _txCommitHandler = TxCommitHandler.getInstance();
+ private static final TxRollbackHandler _txRollbackHandler = TxRollbackHandler.getInstance();
+ private static final BasicRejectMethodHandler _basicRejectMethodHandler = BasicRejectMethodHandler.getInstance();
+
+
+
+ public static MethodDispatcher createMethodDispatcher(AMQStateManager stateManager, ProtocolVersion protocolVersion)
+ {
+ return _dispatcherFactories.get(protocolVersion).createMethodDispatcher(stateManager);
+ }
+
+
+ public ServerMethodDispatcherImpl(AMQStateManager stateManager)
+ {
+ _stateManager = stateManager;
+ }
+
+
+ protected AMQStateManager getStateManager()
+ {
+ return _stateManager;
+ }
+
+
+
+ public boolean dispatchAccessRequest(AccessRequestBody body, int channelId) throws AMQException
+ {
+ _accessRequestHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicAck(BasicAckBody body, int channelId) throws AMQException
+ {
+ _basicAckMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicCancel(BasicCancelBody body, int channelId) throws AMQException
+ {
+ _basicCancelMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicConsume(BasicConsumeBody body, int channelId) throws AMQException
+ {
+ _basicConsumeMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicGet(BasicGetBody body, int channelId) throws AMQException
+ {
+ _basicGetMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicPublish(BasicPublishBody body, int channelId) throws AMQException
+ {
+ _basicPublishMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicQos(BasicQosBody body, int channelId) throws AMQException
+ {
+ _basicQosHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicRecover(BasicRecoverBody body, int channelId) throws AMQException
+ {
+ _basicRecoverMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicReject(BasicRejectBody body, int channelId) throws AMQException
+ {
+ _basicRejectMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchChannelOpen(ChannelOpenBody body, int channelId) throws AMQException
+ {
+ _channelOpenHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+
+ public boolean dispatchAccessRequestOk(AccessRequestOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicCancelOk(BasicCancelOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicConsumeOk(BasicConsumeOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicDeliver(BasicDeliverBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicGetEmpty(BasicGetEmptyBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicGetOk(BasicGetOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicQosOk(BasicQosOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchBasicReturn(BasicReturnBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchChannelClose(ChannelCloseBody body, int channelId) throws AMQException
+ {
+ _channelCloseHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+
+ public boolean dispatchChannelCloseOk(ChannelCloseOkBody body, int channelId) throws AMQException
+ {
+ _channelCloseOkHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+
+ public boolean dispatchChannelFlow(ChannelFlowBody body, int channelId) throws AMQException
+ {
+ _channelFlowHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchChannelFlowOk(ChannelFlowOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchChannelOpenOk(ChannelOpenOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+
+ public boolean dispatchConnectionOpen(ConnectionOpenBody body, int channelId) throws AMQException
+ {
+ _connectionOpenMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+
+ public boolean dispatchConnectionClose(ConnectionCloseBody body, int channelId) throws AMQException
+ {
+ _connectionCloseMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+
+ public boolean dispatchConnectionCloseOk(ConnectionCloseOkBody body, int channelId) throws AMQException
+ {
+ _connectionCloseOkMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionOpenOk(ConnectionOpenOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchConnectionRedirect(ConnectionRedirectBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchConnectionSecure(ConnectionSecureBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchConnectionStart(ConnectionStartBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchConnectionTune(ConnectionTuneBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchDtxSelectOk(DtxSelectOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchDtxStartOk(DtxStartOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchExchangeBoundOk(ExchangeBoundOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchExchangeDeclareOk(ExchangeDeclareOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchExchangeDeleteOk(ExchangeDeleteOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileCancelOk(FileCancelOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileConsumeOk(FileConsumeOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileDeliver(FileDeliverBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileOpen(FileOpenBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileOpenOk(FileOpenOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileQosOk(FileQosOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileReturn(FileReturnBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchFileStage(FileStageBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchQueueBindOk(QueueBindOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchQueueDeclareOk(QueueDeclareOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchQueueDeleteOk(QueueDeleteOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchQueuePurgeOk(QueuePurgeOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchStreamCancelOk(StreamCancelOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchStreamConsumeOk(StreamConsumeOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchStreamDeliver(StreamDeliverBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchStreamQosOk(StreamQosOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchStreamReturn(StreamReturnBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchTxCommitOk(TxCommitOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchTxRollbackOk(TxRollbackOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchTxSelectOk(TxSelectOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+
+ public boolean dispatchConnectionSecureOk(ConnectionSecureOkBody body, int channelId) throws AMQException
+ {
+ _connectionSecureOkMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionStartOk(ConnectionStartOkBody body, int channelId) throws AMQException
+ {
+ _connectionStartOkMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionTuneOk(ConnectionTuneOkBody body, int channelId) throws AMQException
+ {
+ _connectionTuneOkMethodHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchDtxSelect(DtxSelectBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchDtxStart(DtxStartBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchExchangeBound(ExchangeBoundBody body, int channelId) throws AMQException
+ {
+ _exchangeBoundHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchExchangeDeclare(ExchangeDeclareBody body, int channelId) throws AMQException
+ {
+ _exchangeDeclareHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchExchangeDelete(ExchangeDeleteBody body, int channelId) throws AMQException
+ {
+ _exchangeDeleteHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchFileAck(FileAckBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchFileCancel(FileCancelBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchFileConsume(FileConsumeBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchFilePublish(FilePublishBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchFileQos(FileQosBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchFileReject(FileRejectBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchQueueBind(QueueBindBody body, int channelId) throws AMQException
+ {
+ _queueBindHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchQueueDeclare(QueueDeclareBody body, int channelId) throws AMQException
+ {
+ _queueDeclareHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchQueueDelete(QueueDeleteBody body, int channelId) throws AMQException
+ {
+ _queueDeleteHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchQueuePurge(QueuePurgeBody body, int channelId) throws AMQException
+ {
+ _queuePurgeHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchStreamCancel(StreamCancelBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchStreamConsume(StreamConsumeBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchStreamPublish(StreamPublishBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchStreamQos(StreamQosBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTunnelRequest(TunnelRequestBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTxCommit(TxCommitBody body, int channelId) throws AMQException
+ {
+ _txCommitHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchTxRollback(TxRollbackBody body, int channelId) throws AMQException
+ {
+ _txRollbackHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+ public boolean dispatchTxSelect(TxSelectBody body, int channelId) throws AMQException
+ {
+ _txSelectHandler.methodReceived(_stateManager, body, channelId);
+ return true;
+ }
+
+
+
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java new file mode 100644 index 0000000000..97646a015f --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_0_9.java @@ -0,0 +1,160 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.handler;
+
+
+import org.apache.qpid.framing.amqp_0_9.MethodDispatcher_0_9;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.AMQException;
+
+
+
+public class ServerMethodDispatcherImpl_0_9
+ extends ServerMethodDispatcherImpl
+ implements MethodDispatcher_0_9
+
+{
+
+ private static final BasicRecoverSyncMethodHandler _basicRecoverSyncMethodHandler =
+ BasicRecoverSyncMethodHandler.getInstance();
+
+ public ServerMethodDispatcherImpl_0_9(AMQStateManager stateManager)
+ {
+ super(stateManager);
+ }
+
+ public boolean dispatchBasicRecoverSync(BasicRecoverSyncBody body, int channelId) throws AMQException
+ {
+ _basicRecoverSyncMethodHandler.methodReceived(getStateManager(), body, channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicRecoverSyncOk(BasicRecoverSyncOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchChannelOk(ChannelOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelPing(ChannelPingBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelPong(ChannelPongBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelResume(ChannelResumeBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageAppend(MessageAppendBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageCancel(MessageCancelBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageCheckpoint(MessageCheckpointBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageClose(MessageCloseBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageConsume(MessageConsumeBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageEmpty(MessageEmptyBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageGet(MessageGetBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageOffset(MessageOffsetBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageOk(MessageOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageOpen(MessageOpenBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageQos(MessageQosBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageRecover(MessageRecoverBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageReject(MessageRejectBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageResume(MessageResumeBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageTransfer(MessageTransferBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchQueueUnbindOk(QueueUnbindOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchQueueUnbind(QueueUnbindBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java new file mode 100644 index 0000000000..d599ca3d4e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ServerMethodDispatcherImpl_8_0.java @@ -0,0 +1,86 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.handler;
+
+import org.apache.qpid.framing.amqp_8_0.MethodDispatcher_8_0;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.AMQException;
+
+public class ServerMethodDispatcherImpl_8_0
+ extends ServerMethodDispatcherImpl
+ implements MethodDispatcher_8_0
+{
+ public ServerMethodDispatcherImpl_8_0(AMQStateManager stateManager)
+ {
+ super(stateManager);
+ }
+
+ public boolean dispatchBasicRecoverOk(BasicRecoverOkBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchChannelAlert(ChannelAlertBody body, int channelId) throws AMQException
+ {
+ throw new UnexpectedMethodException(body);
+ }
+
+ public boolean dispatchTestContent(TestContentBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestContentOk(TestContentOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestInteger(TestIntegerBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestIntegerOk(TestIntegerOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestString(TestStringBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestStringOk(TestStringOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestTable(TestTableBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestTableOk(TestTableOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java index 3d7ec286f9..79cc722e0e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/TxCommitHandler.java @@ -24,6 +24,8 @@ import org.apache.log4j.Logger; import org.apache.qpid.AMQException; import org.apache.qpid.framing.TxCommitBody; import org.apache.qpid.framing.TxCommitOkBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -45,7 +47,7 @@ public class TxCommitHandler implements StateAwareMethodListener<TxCommitBody> { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<TxCommitBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, TxCommitBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); @@ -53,25 +55,26 @@ public class TxCommitHandler implements StateAwareMethodListener<TxCommitBody> { if (_log.isDebugEnabled()) { - _log.debug("Commit received on channel " + evt.getChannelId()); + _log.debug("Commit received on channel " + channelId); } - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw evt.getMethod().getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } channel.commit(); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(TxCommitOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0)); + + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createTxCommitOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); + channel.processReturns(session); } catch (AMQException e) { - throw evt.getMethod().getChannelException(e.getErrorCode(), "Failed to commit: " + e.getMessage()); + throw body.getChannelException(e.getErrorCode(), "Failed to commit: " + e.getMessage()); } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java index f747f7a840..5f402f3fda 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/TxRollbackHandler.java @@ -23,6 +23,8 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; import org.apache.qpid.framing.TxRollbackBody; import org.apache.qpid.framing.TxRollbackOkBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -42,24 +44,26 @@ public class TxRollbackHandler implements StateAwareMethodListener<TxRollbackBod { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<TxRollbackBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, TxRollbackBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); try { - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw evt.getMethod().getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } channel.rollback(); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(TxRollbackOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0)); + + MethodRegistry methodRegistry = session.getMethodRegistry(); + AMQMethodBody responseBody = methodRegistry.createTxRollbackOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); + + //Now resend all the unacknowledged messages back to the original subscribers. //(Must be done after the TxnRollback-ok response). // Why, are we not allowed to send messages back to client before the ok method? @@ -67,7 +71,7 @@ public class TxRollbackHandler implements StateAwareMethodListener<TxRollbackBod } catch (AMQException e) { - throw evt.getMethod().getChannelException(e.getErrorCode(), "Failed to rollback: " + e.getMessage()); + throw body.getChannelException(e.getErrorCode(), "Failed to rollback: " + e.getMessage()); } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java index a9e478e301..308f5b73cf 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/TxSelectHandler.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.handler; import org.apache.qpid.AMQException; import org.apache.qpid.framing.TxSelectBody; import org.apache.qpid.framing.TxSelectOkBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.state.AMQStateManager; @@ -42,22 +43,21 @@ public class TxSelectHandler implements StateAwareMethodListener<TxSelectBody> { } - public void methodReceived(AMQStateManager stateManager, AMQMethodEvent<TxSelectBody> evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, TxSelectBody body, int channelId) throws AMQException { AMQProtocolSession session = stateManager.getProtocolSession(); - AMQChannel channel = session.getChannel(evt.getChannelId()); + AMQChannel channel = session.getChannel(channelId); if (channel == null) { - throw evt.getMethod().getChannelNotFoundException(evt.getChannelId()); + throw body.getChannelNotFoundException(channelId); } channel.setLocalTransactional(); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(TxSelectOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0)); + MethodRegistry methodRegistry = session.getMethodRegistry(); + TxSelectOkBody responseBody = methodRegistry.createTxSelectOkBody(); + session.writeFrame(responseBody.generateFrame(channelId)); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java b/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java new file mode 100644 index 0000000000..fb18519fe1 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/UnexpectedMethodException.java @@ -0,0 +1,33 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.handler;
+
+
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.AMQException;
+
+public class UnexpectedMethodException extends AMQException
+{
+ public UnexpectedMethodException(AMQMethodBody body)
+ {
+ super("Unexpected method recevied: " + body.getClass().getName());
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java index 8366c426dd..36e7e88fd6 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java @@ -27,8 +27,8 @@ package org.apache.qpid.server.output;
import org.apache.qpid.server.output.ProtocolOutputConverter.Factory;
-import org.apache.qpid.server.output.amqp0_8.ProtocolOutputConverterImpl;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.framing.ProtocolVersion;
import java.util.Map;
import java.util.HashMap;
@@ -36,27 +36,26 @@ import java.util.HashMap; public class ProtocolOutputConverterRegistry
{
- private static final Map<Byte, Map<Byte, Factory>> _registry =
- new HashMap<Byte, Map<Byte, Factory>>();
+ private static final Map<ProtocolVersion, Factory> _registry =
+ new HashMap<ProtocolVersion, Factory>();
static
{
- register((byte) 8, (byte) 0, ProtocolOutputConverterImpl.getInstanceFactory());
+ register(ProtocolVersion.v8_0, org.apache.qpid.server.output.amqp0_8.ProtocolOutputConverterImpl.getInstanceFactory());
+ register(ProtocolVersion.v0_9, org.apache.qpid.server.output.amqp0_9.ProtocolOutputConverterImpl.getInstanceFactory());
+
}
- private static void register(byte major, byte minor, Factory converter)
+ private static void register(ProtocolVersion version, Factory converter)
{
- if(!_registry.containsKey(major))
- {
- _registry.put(major, new HashMap<Byte, Factory>());
- }
- _registry.get(major).put(minor, converter);
+
+ _registry.put(version,converter);
}
public static ProtocolOutputConverter getConverter(AMQProtocolSession session)
{
- return _registry.get(session.getProtocolMajorVersion()).get(session.getProtocolMinorVersion()).newInstance(session);
+ return _registry.get(session.getProtocolVersion()).newInstance(session);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java b/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java index 8462ed9557..1bfe1e3d35 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java @@ -43,6 +43,7 @@ import java.util.Iterator; public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
{
+
public static Factory getInstanceFactory()
{
return new Factory()
@@ -98,7 +99,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter //
ContentChunk cb = messageHandle.getContentChunk(storeContext,messageId, 0);
- AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb));
+ AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb));
AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody};
CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(deliver, headerAndFirstContent);
writeFrame(compositeBlock);
@@ -109,7 +110,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter for(int i = 1; i < bodyCount; i++)
{
cb = messageHandle.getContentChunk(storeContext,messageId, i);
- writeFrame(new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb)));
+ writeFrame(new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb)));
}
@@ -149,7 +150,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter //
ContentChunk cb = messageHandle.getContentChunk(storeContext,messageId, 0);
- AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb));
+ AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb));
AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody};
CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(deliver, headerAndFirstContent);
writeFrame(compositeBlock);
@@ -160,7 +161,7 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter for(int i = 1; i < bodyCount; i++)
{
cb = messageHandle.getContentChunk(storeContext, messageId, i);
- writeFrame(new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb)));
+ writeFrame(new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb)));
}
@@ -176,11 +177,14 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter final MessagePublishInfo pb = message.getMessagePublishInfo();
final AMQMessageHandle messageHandle = message.getMessageHandle();
- AMQFrame deliverFrame = BasicDeliverBody.createAMQFrame(channelId, getProtocolMajorVersion(),
- getProtocolMinorVersion(),
- consumerTag,
- deliveryTag, pb.getExchange(), messageHandle.isRedelivered(),
- pb.getRoutingKey());
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0);
+ BasicDeliverBody deliverBody =
+ methodRegistry.createBasicDeliverBody(consumerTag,
+ deliveryTag,
+ messageHandle.isRedelivered(),
+ pb.getExchange(),
+ pb.getRoutingKey());
+ AMQFrame deliverFrame = deliverBody.generateFrame(channelId);
return deliverFrame.toByteBuffer();
@@ -192,13 +196,14 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter final MessagePublishInfo pb = message.getMessagePublishInfo();
final AMQMessageHandle messageHandle = message.getMessageHandle();
- AMQFrame getOkFrame = BasicGetOkBody.createAMQFrame(channelId,
- getProtocolMajorVersion(),
- getProtocolMinorVersion(),
- deliveryTag, pb.getExchange(),
- queueSize,
- messageHandle.isRedelivered(),
- pb.getRoutingKey());
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0);
+ BasicGetOkBody getOkBody =
+ methodRegistry.createBasicGetOkBody(deliveryTag,
+ messageHandle.isRedelivered(),
+ pb.getExchange(),
+ pb.getRoutingKey(),
+ queueSize);
+ AMQFrame getOkFrame = getOkBody.generateFrame(channelId);
return getOkFrame.toByteBuffer();
}
@@ -215,12 +220,13 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter private ByteBuffer createEncodedReturnFrame(AMQMessage message, int channelId, int replyCode, AMQShortString replyText) throws AMQException
{
- AMQFrame returnFrame = BasicReturnBody.createAMQFrame(channelId,
- getProtocolMajorVersion(),
- getProtocolMinorVersion(),
- message.getMessagePublishInfo().getExchange(),
- replyCode, replyText,
- message.getMessagePublishInfo().getRoutingKey());
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0);
+ BasicReturnBody basicReturnBody =
+ methodRegistry.createBasicReturnBody(replyCode,
+ replyText,
+ message.getMessagePublishInfo().getExchange(),
+ message.getMessagePublishInfo().getRoutingKey());
+ AMQFrame returnFrame = basicReturnBody.generateFrame(channelId);
return returnFrame.toByteBuffer();
}
@@ -272,11 +278,9 @@ public class ProtocolOutputConverterImpl implements ProtocolOutputConverter public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
{
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v8_0);
+ BasicCancelOkBody basicCancelOkBody = methodRegistry.createBasicCancelOkBody(consumerTag);
+ writeFrame(basicCancelOkBody.generateFrame(channelId));
- writeFrame(BasicCancelOkBody.createAMQFrame(channelId,
- getProtocolMajorVersion(),
- getProtocolMinorVersion(),
- consumerTag // consumerTag
- ));
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java b/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java new file mode 100644 index 0000000000..0bc2fcf6f7 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_9/ProtocolOutputConverterImpl.java @@ -0,0 +1,260 @@ +package org.apache.qpid.server.output.amqp0_9;
+
+import org.apache.mina.common.ByteBuffer;
+
+import java.util.Iterator;
+
+import org.apache.qpid.server.output.ProtocolOutputConverter;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.AMQMessage;
+import org.apache.qpid.server.queue.AMQMessageHandle;
+import org.apache.qpid.server.store.StoreContext;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.AMQException;
+
+public class ProtocolOutputConverterImpl implements ProtocolOutputConverter
+{
+
+
+ public static Factory getInstanceFactory()
+ {
+ return new Factory()
+ {
+
+ public ProtocolOutputConverter newInstance(AMQProtocolSession session)
+ {
+ return new ProtocolOutputConverterImpl(session);
+ }
+ };
+ }
+
+ private final AMQProtocolSession _protocolSession;
+
+ private ProtocolOutputConverterImpl(AMQProtocolSession session)
+ {
+ _protocolSession = session;
+ }
+
+
+ public AMQProtocolSession getProtocolSession()
+ {
+ return _protocolSession;
+ }
+
+ public void writeDeliver(AMQMessage message, int channelId, long deliveryTag, AMQShortString consumerTag)
+ throws AMQException
+ {
+ ByteBuffer deliver = createEncodedDeliverFrame(message, channelId, deliveryTag, consumerTag);
+ AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
+ message.getContentHeaderBody());
+
+ final AMQMessageHandle messageHandle = message.getMessageHandle();
+ final StoreContext storeContext = message.getStoreContext();
+ final Long messageId = message.getMessageId();
+
+ final int bodyCount = messageHandle.getBodyCount(storeContext,messageId);
+
+ if(bodyCount == 0)
+ {
+ SmallCompositeAMQDataBlock compositeBlock = new SmallCompositeAMQDataBlock(deliver,
+ contentHeader);
+
+ writeFrame(compositeBlock);
+ }
+ else
+ {
+
+
+ //
+ // Optimise the case where we have a single content body. In that case we create a composite block
+ // so that we can writeDeliver out the deliver, header and body with a single network writeDeliver.
+ //
+ ContentChunk cb = messageHandle.getContentChunk(storeContext,messageId, 0);
+
+ AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb));
+ AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody};
+ CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(deliver, headerAndFirstContent);
+ writeFrame(compositeBlock);
+
+ //
+ // Now start writing out the other content bodies
+ //
+ for(int i = 1; i < bodyCount; i++)
+ {
+ cb = messageHandle.getContentChunk(storeContext,messageId, i);
+ writeFrame(new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb)));
+ }
+
+
+ }
+
+
+ }
+
+
+ public void writeGetOk(AMQMessage message, int channelId, long deliveryTag, int queueSize) throws AMQException
+ {
+
+ final AMQMessageHandle messageHandle = message.getMessageHandle();
+ final StoreContext storeContext = message.getStoreContext();
+ final long messageId = message.getMessageId();
+
+ ByteBuffer deliver = createEncodedGetOkFrame(message, channelId, deliveryTag, queueSize);
+
+
+ AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
+ message.getContentHeaderBody());
+
+ final int bodyCount = messageHandle.getBodyCount(storeContext,messageId);
+ if(bodyCount == 0)
+ {
+ SmallCompositeAMQDataBlock compositeBlock = new SmallCompositeAMQDataBlock(deliver,
+ contentHeader);
+ writeFrame(compositeBlock);
+ }
+ else
+ {
+
+
+ //
+ // Optimise the case where we have a single content body. In that case we create a composite block
+ // so that we can writeDeliver out the deliver, header and body with a single network writeDeliver.
+ //
+ ContentChunk cb = messageHandle.getContentChunk(storeContext,messageId, 0);
+
+ AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb));
+ AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody};
+ CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(deliver, headerAndFirstContent);
+ writeFrame(compositeBlock);
+
+ //
+ // Now start writing out the other content bodies
+ //
+ for(int i = 1; i < bodyCount; i++)
+ {
+ cb = messageHandle.getContentChunk(storeContext, messageId, i);
+ writeFrame(new AMQFrame(channelId, getProtocolSession().getMethodRegistry().getProtocolVersionMethodConverter().convertToBody(cb)));
+ }
+
+
+ }
+
+
+ }
+
+
+ private ByteBuffer createEncodedDeliverFrame(AMQMessage message, int channelId, long deliveryTag, AMQShortString consumerTag)
+ throws AMQException
+ {
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ final AMQMessageHandle messageHandle = message.getMessageHandle();
+
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
+ BasicDeliverBody deliverBody =
+ methodRegistry.createBasicDeliverBody(consumerTag,
+ deliveryTag,
+ messageHandle.isRedelivered(),
+ pb.getExchange(),
+ pb.getRoutingKey());
+ AMQFrame deliverFrame = deliverBody.generateFrame(channelId);
+
+
+ return deliverFrame.toByteBuffer();
+ }
+
+ private ByteBuffer createEncodedGetOkFrame(AMQMessage message, int channelId, long deliveryTag, int queueSize)
+ throws AMQException
+ {
+ final MessagePublishInfo pb = message.getMessagePublishInfo();
+ final AMQMessageHandle messageHandle = message.getMessageHandle();
+
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
+ BasicGetOkBody getOkBody =
+ methodRegistry.createBasicGetOkBody(deliveryTag,
+ messageHandle.isRedelivered(),
+ pb.getExchange(),
+ pb.getRoutingKey(),
+ queueSize);
+ AMQFrame getOkFrame = getOkBody.generateFrame(channelId);
+
+ return getOkFrame.toByteBuffer();
+ }
+
+ public byte getProtocolMinorVersion()
+ {
+ return getProtocolSession().getProtocolMinorVersion();
+ }
+
+ public byte getProtocolMajorVersion()
+ {
+ return getProtocolSession().getProtocolMajorVersion();
+ }
+
+ private ByteBuffer createEncodedReturnFrame(AMQMessage message, int channelId, int replyCode, AMQShortString replyText) throws AMQException
+ {
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
+ BasicReturnBody basicReturnBody =
+ methodRegistry.createBasicReturnBody(replyCode,
+ replyText,
+ message.getMessagePublishInfo().getExchange(),
+ message.getMessagePublishInfo().getRoutingKey());
+ AMQFrame returnFrame = basicReturnBody.generateFrame(channelId);
+
+ return returnFrame.toByteBuffer();
+ }
+
+ public void writeReturn(AMQMessage message, int channelId, int replyCode, AMQShortString replyText)
+ throws AMQException
+ {
+ ByteBuffer returnFrame = createEncodedReturnFrame(message, channelId, replyCode, replyText);
+
+ AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId,
+ message.getContentHeaderBody());
+
+ Iterator<AMQDataBlock> bodyFrameIterator = message.getBodyFrameIterator(getProtocolSession(), channelId);
+ //
+ // Optimise the case where we have a single content body. In that case we create a composite block
+ // so that we can writeDeliver out the deliver, header and body with a single network writeDeliver.
+ //
+ if (bodyFrameIterator.hasNext())
+ {
+ AMQDataBlock firstContentBody = bodyFrameIterator.next();
+ AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody};
+ CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(returnFrame, headerAndFirstContent);
+ writeFrame(compositeBlock);
+ }
+ else
+ {
+ CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(returnFrame,
+ new AMQDataBlock[]{contentHeader});
+
+ writeFrame(compositeBlock);
+ }
+
+ //
+ // Now start writing out the other content bodies
+ // TODO: MINA needs to be fixed so the the pending writes buffer is not unbounded
+ //
+ while (bodyFrameIterator.hasNext())
+ {
+ writeFrame(bodyFrameIterator.next());
+ }
+ }
+
+
+ public void writeFrame(AMQDataBlock block)
+ {
+ getProtocolSession().writeFrame(block);
+ }
+
+
+ public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag)
+ {
+ MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9);
+ BasicCancelOkBody basicCancelOkBody = methodRegistry.createBasicCancelOkBody(consumerTag);
+ writeFrame(basicCancelOkBody.generateFrame(channelId));
+
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index 5bfd47b469..0fe6d3636e 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -39,6 +39,7 @@ import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.handler.ServerMethodDispatcherImpl; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.output.ProtocolOutputConverter; @@ -107,10 +108,11 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable private FieldTable _clientProperties; private final List<Task> _taskList = new CopyOnWriteArrayList<Task>(); - private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion); + private List<Integer> _closingChannelsList = new ArrayList<Integer>(); private ProtocolOutputConverter _protocolOutputConverter; private Principal _authorizedID; + private MethodDispatcher _dispatcher; public ManagedObject getManagedObject() { @@ -235,24 +237,24 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable ((AMQDecoder) _codecFactory.getDecoder()).setExpectProtocolInitiation(false); try { - pi.checkVersion(); // Fails if not correct + ProtocolVersion pv = pi.checkVersion(); // Fails if not correct // This sets the protocol version (and hence framing classes) for this session. - setProtocolVersion(pi._protocolMajor, pi._protocolMinor); + setProtocolVersion(pv); String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager().getMechanisms(); String locales = "en_US"; - // Interfacing with generated code - be aware of possible changes to parameter order as versions change. - AMQFrame response = - ConnectionStartBody.createAMQFrame((short) 0, getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - locales.getBytes(), // locales - mechanisms.getBytes(), // mechanisms - null, // serverProperties - (short) getProtocolMajorVersion(), // versionMajor - (short) getProtocolMinorVersion()); // versionMinor - _minaProtocolSession.write(response); + + AMQMethodBody responseBody = getMethodRegistry().createConnectionStartBody((short) getProtocolMajorVersion(), + (short) getProtocolMinorVersion(), + null, + mechanisms.getBytes(), + locales.getBytes()); + _minaProtocolSession.write(responseBody.generateFrame(0)); + + } catch (AMQException e) { @@ -548,6 +550,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable public void closeChannelOk(int channelId) { + removeChannel(channelId); _closingChannelsList.remove(new Integer(channelId)); } @@ -695,13 +698,12 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable } } - private void setProtocolVersion(byte major, byte minor) + private void setProtocolVersion(ProtocolVersion pv) { - _protocolVersion = new ProtocolVersion(major, minor); - - _registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion); + _protocolVersion = pv; _protocolOutputConverter = ProtocolOutputConverterRegistry.getConverter(this); + _dispatcher = ServerMethodDispatcherImpl.createMethodDispatcher(_stateManager, _protocolVersion); } public byte getProtocolMajorVersion() @@ -709,6 +711,11 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable return _protocolVersion.getMajorVersion(); } + public ProtocolVersion getProtocolVersion() + { + return _protocolVersion; + } + public byte getProtocolMinorVersion() { return _protocolVersion.getMinorVersion(); @@ -719,9 +726,9 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable return (getProtocolMajorVersion() == major) && (getProtocolMinorVersion() == minor); } - public VersionSpecificRegistry getRegistry() + public MethodRegistry getRegistry() { - return _registry; + return getMethodRegistry(); } public Object getClientIdentifier() @@ -766,6 +773,16 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, Managable return _authorizedID; } + public MethodRegistry getMethodRegistry() + { + return MethodRegistry.getMethodRegistry(getProtocolVersion()); + } + + public MethodDispatcher getMethodDispatcher() + { + return _dispatcher; + } + public String getClientVersion() { return (_clientVersion == null) ? null : _clientVersion.toString(); diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java index 476e608b01..06f2fbcfd7 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java @@ -30,13 +30,7 @@ import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.util.SessionUtil; import org.apache.qpid.AMQException; import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQProtocolHeaderException; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.HeartbeatBody; -import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.framing.*; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.transport.ConnectorConfiguration; @@ -177,15 +171,12 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter { _logger.error("Exception caught in" + session + ", closing session explictly: " + throwable, throwable); - // Be aware of possible changes to parameter order as versions change. - protocolSession.write(ConnectionCloseBody.createAMQFrame(0, - session.getProtocolMajorVersion(), - session.getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - 200, // replyCode - new AMQShortString(throwable.getMessage()) // replyText - )); + + MethodRegistry methodRegistry = MethodRegistry.getMethodRegistry(session.getProtocolVersion()); + ConnectionCloseBody closeBody = methodRegistry.createConnectionCloseBody(200,new AMQShortString(throwable.getMessage()),0,0); + + protocolSession.write(closeBody.generateFrame(0)); + protocolSession.close(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java index 390117acf6..c9316f7405 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java @@ -23,9 +23,7 @@ package org.apache.qpid.server.protocol; import javax.security.sasl.SaslServer; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.output.ProtocolOutputConverter; @@ -37,6 +35,8 @@ import java.security.Principal; public interface AMQProtocolSession extends AMQVersionAwareProtocolSession { + + public static interface Task { public void doTask(AMQProtocolSession session) throws AMQException; @@ -172,4 +172,8 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession /** @return a Principal that was used to authorized this session */ Principal getAuthorizedID(); + public MethodRegistry getMethodRegistry(); + + public MethodDispatcher getMethodDispatcher(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java index 66f928a70e..bd072985c4 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java @@ -61,6 +61,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.management.AMQManagedObject; @@ -261,17 +262,17 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed */ public void closeConnection() throws JMException { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame response = - ConnectionCloseBody.createAMQFrame(0, _session.getProtocolMajorVersion(), _session.getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION // replyText - ); - _session.writeFrame(response); + + MethodRegistry methodRegistry = _session.getMethodRegistry(); + ConnectionCloseBody responseBody = + methodRegistry.createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), + // replyCode + BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION, + // replyText, + 0, + 0); + + _session.writeFrame(responseBody.generateFrame(0)); try { diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java index dd9f32a306..307a4c8d21 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java @@ -187,7 +187,7 @@ public class AMQMessage private ProtocolVersionMethodConverter getProtocolVersionMethodConverter() { - return _protocolSession.getRegistry().getProtocolVersionMethodConverter(); + return _protocolSession.getMethodRegistry().getProtocolVersionMethodConverter(); } public void remove() diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java index f96900d0a9..c5b3099f58 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java @@ -28,37 +28,11 @@ import java.util.concurrent.CopyOnWriteArraySet; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.BasicAckBody; -import org.apache.qpid.framing.BasicCancelBody; -import org.apache.qpid.framing.BasicConsumeBody; -import org.apache.qpid.framing.BasicGetBody; -import org.apache.qpid.framing.BasicPublishBody; -import org.apache.qpid.framing.BasicQosBody; -import org.apache.qpid.framing.BasicRecoverBody; -import org.apache.qpid.framing.BasicRejectBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelFlowBody; -import org.apache.qpid.framing.ChannelOpenBody; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.framing.ConnectionOpenBody; -import org.apache.qpid.framing.ConnectionSecureOkBody; -import org.apache.qpid.framing.ConnectionStartOkBody; -import org.apache.qpid.framing.ConnectionTuneOkBody; -import org.apache.qpid.framing.ExchangeBoundBody; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeleteBody; -import org.apache.qpid.framing.QueueBindBody; -import org.apache.qpid.framing.QueueDeclareBody; -import org.apache.qpid.framing.QueueDeleteBody; -import org.apache.qpid.framing.QueuePurgeBody; -import org.apache.qpid.framing.TxCommitBody; -import org.apache.qpid.framing.TxRollbackBody; -import org.apache.qpid.framing.TxSelectBody; +import org.apache.qpid.AMQConnectionException; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; +import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.handler.BasicAckMethodHandler; import org.apache.qpid.server.handler.BasicCancelMethodHandler; import org.apache.qpid.server.handler.BasicConsumeMethodHandler; @@ -107,43 +81,35 @@ public class AMQStateManager implements AMQMethodListener * Maps from an AMQState instance to a Map from Class to StateTransitionHandler. The class must be a subclass of * AMQFrame. */ - private final EnumMap<AMQState, Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>> _state2HandlersMap = +/* private final EnumMap<AMQState, Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>> _state2HandlersMap = new EnumMap<AMQState, Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>>( AMQState.class); + */ + private CopyOnWriteArraySet<StateListener> _stateListeners = new CopyOnWriteArraySet<StateListener>(); public AMQStateManager(VirtualHostRegistry virtualHostRegistry, AMQProtocolSession protocolSession) { - this(AMQState.CONNECTION_NOT_STARTED, true, virtualHostRegistry, protocolSession); - } - protected AMQStateManager(AMQState initial, boolean register, VirtualHostRegistry virtualHostRegistry, - AMQProtocolSession protocolSession) - { _virtualHostRegistry = virtualHostRegistry; _protocolSession = protocolSession; - _currentState = initial; - if (register) - { - registerListeners(); - } + _currentState = AMQState.CONNECTION_NOT_STARTED; + } + /* protected void registerListeners() { Map<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>> frame2handlerMap; frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - frame2handlerMap.put(ConnectionStartOkBody.class, ConnectionStartOkMethodHandler.getInstance()); _state2HandlersMap.put(AMQState.CONNECTION_NOT_STARTED, frame2handlerMap); frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - frame2handlerMap.put(ConnectionSecureOkBody.class, ConnectionSecureOkMethodHandler.getInstance()); _state2HandlersMap.put(AMQState.CONNECTION_NOT_AUTH, frame2handlerMap); frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - frame2handlerMap.put(ConnectionTuneOkBody.class, ConnectionTuneOkMethodHandler.getInstance()); _state2HandlersMap.put(AMQState.CONNECTION_NOT_TUNED, frame2handlerMap); frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); @@ -154,37 +120,41 @@ public class AMQStateManager implements AMQMethodListener // ConnectionOpen handlers // frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - frame2handlerMap.put(ChannelOpenBody.class, ChannelOpenHandler.getInstance()); - frame2handlerMap.put(ChannelCloseBody.class, ChannelCloseHandler.getInstance()); - frame2handlerMap.put(ChannelCloseOkBody.class, ChannelCloseOkHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - frame2handlerMap.put(ExchangeDeclareBody.class, ExchangeDeclareHandler.getInstance()); - frame2handlerMap.put(ExchangeDeleteBody.class, ExchangeDeleteHandler.getInstance()); - frame2handlerMap.put(ExchangeBoundBody.class, ExchangeBoundHandler.getInstance()); - frame2handlerMap.put(BasicAckBody.class, BasicAckMethodHandler.getInstance()); - frame2handlerMap.put(BasicRecoverBody.class, BasicRecoverMethodHandler.getInstance()); - frame2handlerMap.put(BasicConsumeBody.class, BasicConsumeMethodHandler.getInstance()); - frame2handlerMap.put(BasicGetBody.class, BasicGetMethodHandler.getInstance()); - frame2handlerMap.put(BasicCancelBody.class, BasicCancelMethodHandler.getInstance()); - frame2handlerMap.put(BasicPublishBody.class, BasicPublishMethodHandler.getInstance()); - frame2handlerMap.put(BasicQosBody.class, BasicQosHandler.getInstance()); - frame2handlerMap.put(QueueBindBody.class, QueueBindHandler.getInstance()); - frame2handlerMap.put(QueueDeclareBody.class, QueueDeclareHandler.getInstance()); - frame2handlerMap.put(QueueDeleteBody.class, QueueDeleteHandler.getInstance()); - frame2handlerMap.put(QueuePurgeBody.class, QueuePurgeHandler.getInstance()); - frame2handlerMap.put(ChannelFlowBody.class, ChannelFlowHandler.getInstance()); - frame2handlerMap.put(TxSelectBody.class, TxSelectHandler.getInstance()); - frame2handlerMap.put(TxCommitBody.class, TxCommitHandler.getInstance()); - frame2handlerMap.put(TxRollbackBody.class, TxRollbackHandler.getInstance()); - frame2handlerMap.put(BasicRejectBody.class, BasicRejectMethodHandler.getInstance()); + ChannelOpenHandler.getInstance(); + ChannelCloseHandler.getInstance(); + ChannelCloseOkHandler.getInstance(); + ConnectionCloseMethodHandler.getInstance(); + ConnectionCloseOkMethodHandler.getInstance(); + ConnectionTuneOkMethodHandler.getInstance(); + ConnectionSecureOkMethodHandler.getInstance(); + ConnectionStartOkMethodHandler.getInstance(); + ExchangeDeclareHandler.getInstance(); + ExchangeDeleteHandler.getInstance(); + ExchangeBoundHandler.getInstance(); + BasicAckMethodHandler.getInstance(); + BasicRecoverMethodHandler.getInstance(); + BasicConsumeMethodHandler.getInstance(); + BasicGetMethodHandler.getInstance(); + BasicCancelMethodHandler.getInstance(); + BasicPublishMethodHandler.getInstance(); + BasicQosHandler.getInstance(); + QueueBindHandler.getInstance(); + QueueDeclareHandler.getInstance(); + QueueDeleteHandler.getInstance(); + QueuePurgeHandler.getInstance(); + ChannelFlowHandler.getInstance(); + TxSelectHandler.getInstance(); + TxCommitHandler.getInstance(); + TxRollbackHandler.getInstance(); + BasicRejectMethodHandler.getInstance(); _state2HandlersMap.put(AMQState.CONNECTION_OPEN, frame2handlerMap); frame2handlerMap = new HashMap<Class<? extends AMQMethodBody>, StateAwareMethodListener<? extends AMQMethodBody>>(); - frame2handlerMap.put(ConnectionCloseOkBody.class, ConnectionCloseOkMethodHandler.getInstance()); + _state2HandlersMap.put(AMQState.CONNECTION_CLOSING, frame2handlerMap); - } + } */ public AMQState getCurrentState() { @@ -214,18 +184,25 @@ public class AMQStateManager implements AMQMethodListener public <B extends AMQMethodBody> boolean methodReceived(AMQMethodEvent<B> evt) throws AMQException { - StateAwareMethodListener<B> handler = findStateTransitionHandler(_currentState, evt.getMethod()); - if (handler != null) - { + MethodDispatcher dispatcher = _protocolSession.getMethodDispatcher(); + + final int channelId = evt.getChannelId(); + B body = evt.getMethod(); - checkChannel(evt, _protocolSession); + if(channelId != 0 && _protocolSession.getChannel(channelId)== null) + { - handler.methodReceived(this, evt); + if(! ((body instanceof ChannelOpenBody) + || (body instanceof ChannelCloseOkBody) + || (body instanceof ChannelCloseBody))) + { + throw body.getConnectionException(AMQConstant.CHANNEL_ERROR, "channel is closed"); + } - return true; } - return false; + return body.execute(dispatcher, channelId); + } private <B extends AMQMethodBody> void checkChannel(AMQMethodEvent<B> evt, AMQProtocolSession protocolSession) @@ -239,6 +216,7 @@ public class AMQStateManager implements AMQMethodListener } } +/* protected <B extends AMQMethodBody> StateAwareMethodListener<B> findStateTransitionHandler(AMQState currentState, B frame) // throws IllegalStateTransitionException @@ -260,6 +238,7 @@ public class AMQStateManager implements AMQMethodListener return handler; } } +*/ public void addStateListener(StateListener listener) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java b/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java index e3af0bc486..3c11bb8a9c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java +++ b/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java @@ -29,7 +29,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; * the opportunity to update state. * */ -public interface StateAwareMethodListener <B extends AMQMethodBody> +public interface StateAwareMethodListener<B extends AMQMethodBody> { - void methodReceived(AMQStateManager stateManager, AMQMethodEvent<B> evt) throws AMQException; + void methodReceived(AMQStateManager stateManager, B evt, int channelId) throws AMQException; } diff --git a/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java b/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java index b8803206e0..d8b5f5f7e6 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java +++ b/java/broker/src/test/java/org/apache/qpid/server/RunBrokerWithCommand.java @@ -43,7 +43,7 @@ public class RunBrokerWithCommand } catch (Exception e) { - System.out.println("Unable to start broker due to: " + e.getMessage()); + System.err.println("Unable to start broker due to: " + e.getMessage()); e.printStackTrace(); exit(1); @@ -55,7 +55,7 @@ public class RunBrokerWithCommand try { Process task = Runtime.getRuntime().exec(args[0]); - System.out.println("Started Proccess: " + args[0]); + System.err.println("Started Proccess: " + args[0]); InputStream inputStream = task.getInputStream(); @@ -70,19 +70,21 @@ public class RunBrokerWithCommand out.join(); err.join(); - System.out.println("Waiting for process to exit: " + args[0]); + System.err.println("Waiting for process to exit: " + args[0]); task.waitFor(); - System.out.println("Done Proccess: " + args[0]); + System.err.println("Done Proccess: " + args[0]); } catch (IOException e) { - System.out.println("Proccess had problems: " + e.getMessage()); + System.err.println("Proccess had problems: " + e.getMessage()); + e.printStackTrace(System.err); exit(1); } catch (InterruptedException e) { - System.out.println("Proccess had problems: " + e.getMessage()); + System.err.println("Proccess had problems: " + e.getMessage()); + e.printStackTrace(System.err); exit(1); } diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java index 3caf6ad73d..4770779363 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueMBeanTest.java @@ -288,7 +288,7 @@ public class AMQQueueMBeanTest extends TestCase // Add the body so we have somthing to test later currentMessage.addContentBodyFrame(_storeContext, - _protocolSession.getRegistry() + _protocolSession.getMethodRegistry() .getProtocolVersionMethodConverter() .convertToContentChunk( new ContentBody(ByteBuffer.allocate((int) MESSAGE_SIZE), diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index 9abc94b3df..85a5fbf996 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -579,19 +579,17 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect throws AMQException, FailoverException { + ChannelOpenBody channelOpenBody = getProtocolHandler().getMethodRegistry().createChannelOpenBody(null); + // TODO: Be aware of possible changes to parameter order as versions change. - _protocolHandler.syncWrite(ChannelOpenBody.createAMQFrame(channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), null), // outOfBand - ChannelOpenOkBody.class); + _protocolHandler.syncWrite(channelOpenBody.generateFrame(channelId), ChannelOpenOkBody.class); + + BasicQosBody basicQosBody = getProtocolHandler().getMethodRegistry().createBasicQosBody(0,prefetchHigh,false); // todo send low water mark when protocol allows. // todo Be aware of possible changes to parameter order as versions change. - _protocolHandler.syncWrite(BasicQosBody.createAMQFrame(channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), false, // global - prefetchHigh, // prefetchCount - 0), // prefetchSize - BasicQosOkBody.class); + _protocolHandler.syncWrite(basicQosBody.generateFrame(channelId),BasicQosOkBody.class); if (transacted) { @@ -600,9 +598,10 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _logger.debug("Issuing TxSelect for " + channelId); } + TxSelectBody body = getProtocolHandler().getMethodRegistry().createTxSelectBody(); + // TODO: Be aware of possible changes to parameter order as versions change. - _protocolHandler.syncWrite(TxSelectBody.createAMQFrame(channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion()), TxSelectOkBody.class); + _protocolHandler.syncWrite(body.generateFrame(channelId), TxSelectOkBody.class); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java b/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java index 1a2fe0d355..90d5271145 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQHeadersExchange.java @@ -54,6 +54,6 @@ public class AMQHeadersExchange extends AMQDestination //Not sure what the best approach is here, probably to treat this like a topic //and allow server to generate names. As it is AMQ specific it doesn't need to //fit the JMS API expectations so this is not as yet critical. - return false; + return getAMQQueueName() == null; } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 804c846572..15c113a05d 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -40,34 +40,9 @@ import org.apache.qpid.client.message.UnprocessedMessage; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.util.FlowControllingBlockingQueue; import org.apache.qpid.common.AMQPFilterTypes; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicAckBody; -import org.apache.qpid.framing.BasicConsumeBody; -import org.apache.qpid.framing.BasicConsumeOkBody; -import org.apache.qpid.framing.BasicRecoverBody; -import org.apache.qpid.framing.BasicRecoverOkBody; -import org.apache.qpid.framing.BasicRejectBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelFlowBody; -import org.apache.qpid.framing.ChannelFlowOkBody; -import org.apache.qpid.framing.ExchangeBoundBody; -import org.apache.qpid.framing.ExchangeBoundOkBody; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeclareOkBody; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; -import org.apache.qpid.framing.QueueBindBody; -import org.apache.qpid.framing.QueueBindOkBody; -import org.apache.qpid.framing.QueueDeclareBody; -import org.apache.qpid.framing.QueueDeclareOkBody; -import org.apache.qpid.framing.QueueDeleteBody; -import org.apache.qpid.framing.QueueDeleteOkBody; -import org.apache.qpid.framing.TxCommitBody; -import org.apache.qpid.framing.TxCommitOkBody; -import org.apache.qpid.framing.TxRollbackBody; -import org.apache.qpid.framing.TxRollbackOkBody; +import org.apache.qpid.framing.*; +import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9; +import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0; import org.apache.qpid.jms.Session; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; @@ -436,9 +411,10 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public void acknowledgeMessage(long deliveryTag, boolean multiple) { - final AMQFrame ackFrame = - BasicAckBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), deliveryTag, - multiple); + + BasicAckBody body = getMethodRegistry().createBasicAckBody(deliveryTag, multiple); + + final AMQFrame ackFrame = body.generateFrame(_channelId); if (_logger.isDebugEnabled()) { @@ -448,6 +424,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi getProtocolHandler().writeFrame(ackFrame); } + public MethodRegistry getMethodRegistry() + { + MethodRegistry methodRegistry = getProtocolHandler().getMethodRegistry(); + return methodRegistry; + } + /** * Binds the named queue, with the specified routing key, to the named exchange. * @@ -470,16 +452,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { public Object execute() throws AMQException, FailoverException { - AMQFrame queueBind = - QueueBindBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), - arguments, // arguments - exchangeName, // exchange - false, // nowait - queueName, // queue - routingKey, // routingKey - getTicket()); // ticket + QueueBindBody body = getMethodRegistry().createQueueBindBody(getTicket(),queueName,exchangeName,routingKey,false,arguments); + + AMQFrame queueBind = body.generateFrame(_channelId); - getProtocolHandler().syncWrite(queueBind, QueueBindOkBody.class); + getProtocolHandler().syncWrite(queueBind, QueueBindOkBody.class); return null; } @@ -526,16 +503,13 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { - getProtocolHandler().closeSession(this); + ChannelCloseBody body = getMethodRegistry().createChannelCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), + new AMQShortString("JMS client closing channel"), 0, 0); - final AMQFrame frame = - ChannelCloseBody.createAMQFrame(getChannelId(), getProtocolMajorVersion(), getProtocolMinorVersion(), - 0, // classId - 0, // methodId - AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - new AMQShortString("JMS client closing channel")); // replyText + final AMQFrame frame = body.generateFrame(getChannelId()); - getProtocolHandler().syncWrite(frame, ChannelCloseOkBody.class, timeout); + getProtocolHandler().syncWrite(frame, ChannelCloseOkBody.class, timeout); + // When control resumes at this point, a reply will have been received that // indicates the broker has closed the channel successfully. @@ -656,8 +630,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi // Commits outstanding messages sent and outstanding acknowledgements. final AMQProtocolHandler handler = getProtocolHandler(); - handler.syncWrite(TxCommitBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion()), - TxCommitOkBody.class); + TxCommitBody body = getMethodRegistry().createTxCommitBody(); + + handler.syncWrite(body.generateFrame(_channelId), TxCommitOkBody.class); markClean(); } @@ -990,18 +965,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { public Object execute() throws AMQException, FailoverException { - AMQFrame queueDeclare = - QueueDeclareBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), - null, // arguments - autoDelete, // autoDelete - durable, // durable - exclusive, // exclusive - false, // nowait - false, // passive - name, // queue - getTicket()); // ticket + QueueDeclareBody body = getMethodRegistry().createQueueDeclareBody(getTicket(),name,false,durable,exclusive,autoDelete,false,null); + + AMQFrame queueDeclare = body.generateFrame(_channelId); - getProtocolHandler().syncWrite(queueDeclare, QueueDeclareOkBody.class); + getProtocolHandler().syncWrite(queueDeclare, QueueDeclareOkBody.class); return null; } @@ -1309,7 +1277,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } else { - _highestDeliveryTag.set(message.getDeliverBody().deliveryTag); + _highestDeliveryTag.set(message.getDeliverBody().getDeliveryTag()); _queue.add(message); } } @@ -1371,16 +1339,29 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi if (isStrictAMQP()) { // We can't use the BasicRecoverBody-OK method as it isn't part of the spec. - _connection.getProtocolHandler().writeFrame(BasicRecoverBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), false)); // requeue + + BasicRecoverBody body = getMethodRegistry().createBasicRecoverBody(false); + _connection.getProtocolHandler().writeFrame(body.generateFrame(_channelId)); _logger.warn("Session Recover cannot be guaranteed with STRICT_AMQP. Messages may arrive out of order."); } else { - - _connection.getProtocolHandler().syncWrite( - BasicRecoverBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), false) // requeue - , BasicRecoverOkBody.class); + // in Qpid the 0-8 spec was hacked to have a recover-ok method... this is bad + // in 0-9 we used the cleaner addition of a new sync recover method with its own ok + if(getProtocolVersion().equals(ProtocolVersion.v8_0)) + { + BasicRecoverBody body = getMethodRegistry().createBasicRecoverBody(false); + _connection.getProtocolHandler().syncWrite(body.generateFrame(_channelId), BasicRecoverOkBody.class); + } + else if(getProtocolVersion().equals(ProtocolVersion.v0_9)) + { + BasicRecoverSyncBody body = ((MethodRegistry_0_9)getMethodRegistry()).createBasicRecoverSyncBody(false); + _connection.getProtocolHandler().syncWrite(body.generateFrame(_channelId), BasicRecoverSyncOkBody.class); + } + else + { + throw new RuntimeException("Unsupported version of the AMQP Protocol: " + getProtocolVersion()); + } } if (!isSuspended) @@ -1398,15 +1379,20 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } + private ProtocolVersion getProtocolVersion() + { + return getProtocolHandler().getProtocolVersion(); + } + public void rejectMessage(UnprocessedMessage message, boolean requeue) { if (_logger.isTraceEnabled()) { - _logger.trace("Rejecting Unacked message:" + message.getDeliverBody().deliveryTag); + _logger.trace("Rejecting Unacked message:" + message.getDeliverBody().getDeliveryTag()); } - rejectMessage(message.getDeliverBody().deliveryTag, requeue); + rejectMessage(message.getDeliverBody().getDeliveryTag(), requeue); } public void rejectMessage(AbstractJMSMessage message, boolean requeue) @@ -1429,11 +1415,10 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _logger.debug("Rejecting delivery tag:" + deliveryTag + ":SessionHC:" + this.hashCode()); } - AMQFrame basicRejectBody = - BasicRejectBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), deliveryTag, - requeue); + BasicRejectBody body = getMethodRegistry().createBasicRejectBody(deliveryTag, requeue); + AMQFrame frame = body.generateFrame(_channelId); - _connection.getProtocolHandler().writeFrame(basicRejectBody); + _connection.getProtocolHandler().writeFrame(frame); } } @@ -1469,8 +1454,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _dispatcher.rollback(); } - _connection.getProtocolHandler().syncWrite(TxRollbackBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion()), TxRollbackOkBody.class); + TxRollbackBody body = getMethodRegistry().createTxRollbackBody(); + AMQFrame frame = body.generateFrame(getChannelId()); + getProtocolHandler().syncWrite(frame, TxRollbackOkBody.class); markClean(); @@ -1728,16 +1714,13 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { AMQMethodEvent response = - new FailoverRetrySupport<AMQMethodEvent, AMQException>( - new FailoverProtectedOperation<AMQMethodEvent, AMQException>() - { - public AMQMethodEvent execute() throws AMQException, FailoverException - { - AMQFrame boundFrame = - ExchangeBoundBody.createAMQFrame(_channelId, getProtocolMajorVersion(), - getProtocolMinorVersion(), exchangeName, // exchange - queueName, // queue - routingKey); // routingKey + new FailoverRetrySupport<AMQMethodEvent, AMQException>( + new FailoverProtectedOperation<AMQMethodEvent, AMQException>() + { + public AMQMethodEvent execute() throws AMQException, FailoverException + { + ExchangeBoundBody body = getMethodRegistry().createExchangeBoundBody(exchangeName, routingKey, queueName); + AMQFrame boundFrame = body.generateFrame(_channelId); return getProtocolHandler().syncWrite(boundFrame, ExchangeBoundOkBody.class); @@ -1747,7 +1730,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi // Extract and return the response code from the query. ExchangeBoundOkBody responseBody = (ExchangeBoundOkBody) response.getMethod(); - return (responseBody.replyCode == 0); + return (responseBody.getReplyCode() == 0); } catch (AMQException e) { @@ -2092,16 +2075,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame jmsConsume = - BasicConsumeBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), arguments, // arguments - tag, // consumerTag - consumer.isExclusive(), // exclusive - consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, // noAck - consumer.isNoLocal(), // noLocal - nowait, // nowait - queueName, // queue - getTicket()); // ticket + BasicConsumeBody body = getMethodRegistry().createBasicConsumeBody(getTicket(), + queueName, + tag, + consumer.isNoLocal(), + consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, + consumer.isExclusive(), + nowait, + arguments); + + + AMQFrame jmsConsume = body.generateFrame(_channelId); if (nowait) { @@ -2171,17 +2155,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { public Object execute() throws AMQException, FailoverException { - AMQFrame exchangeDeclare = - ExchangeDeclareBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), - null, // arguments - false, // autoDelete - false, // durable - name, // exchange - false, // internal - nowait, // nowait - false, // passive - getTicket(), // ticket - type); // type + ExchangeDeclareBody body = getMethodRegistry().createExchangeDeclareBody(getTicket(),name,type,false,false,false,false,nowait,null); + AMQFrame exchangeDeclare = body.generateFrame(_channelId); protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class); @@ -2224,16 +2199,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi amqd.setQueueName(protocolHandler.generateQueueName()); } - AMQFrame queueDeclare = - QueueDeclareBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), - null, // arguments - amqd.isAutoDelete(), // autoDelete - amqd.isDurable(), // durable - amqd.isExclusive(), // exclusive - false, // nowait - false, // passive - amqd.getAMQQueueName(), // queue - getTicket()); // ticket + QueueDeclareBody body = getMethodRegistry().createQueueDeclareBody(getTicket(),amqd.getAMQQueueName(),false,amqd.isDurable(),amqd.isExclusive(),amqd.isAutoDelete(),false,null); + + AMQFrame queueDeclare = body.generateFrame(_channelId); protocolHandler.syncWrite(queueDeclare, QueueDeclareOkBody.class); @@ -2260,13 +2228,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { public Object execute() throws AMQException, FailoverException { - AMQFrame queueDeleteFrame = - QueueDeleteBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), - false, // ifEmpty - false, // ifUnused - true, // nowait - queueName, // queue - getTicket()); // ticket + QueueDeleteBody body = getMethodRegistry().createQueueDeleteBody(getTicket(), + queueName, + false, + false, + true); + AMQFrame queueDeleteFrame = body.generateFrame(_channelId); getProtocolHandler().syncWrite(queueDeleteFrame, QueueDeleteOkBody.class); @@ -2450,12 +2417,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { UnprocessedMessage message = (UnprocessedMessage) messages.next(); - if ((consumerTag == null) || message.getDeliverBody().consumerTag.equals(consumerTag)) + if ((consumerTag == null) || message.getDeliverBody().getConsumerTag().equals(consumerTag)) { if (_logger.isDebugEnabled()) { _logger.debug("Removing message(" + System.identityHashCode(message) + ") from _queue DT:" - + message.getDeliverBody().deliveryTag); + + message.getDeliverBody().getDeliveryTag()); } messages.remove(); @@ -2503,12 +2470,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { // Bounced message is processed here, away from the mina thread AbstractJMSMessage bouncedMessage = - _messageFactoryRegistry.createMessage(0, false, message.getBounceBody().exchange, - message.getBounceBody().routingKey, message.getContentHeader(), message.getBodies()); + _messageFactoryRegistry.createMessage(0, false, message.getBounceBody().getExchange(), + message.getBounceBody().getRoutingKey(), message.getContentHeader(), message.getBodies()); - AMQConstant errorCode = AMQConstant.getConstant(message.getBounceBody().replyCode); - AMQShortString reason = message.getBounceBody().replyText; - _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); + AMQConstant errorCode = AMQConstant.getConstant(message.getBounceBody().getReplyCode()); + AMQShortString reason = message.getBounceBody().getReplyText(); + _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); // @TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. if (errorCode == AMQConstant.NO_CONSUMERS) @@ -2558,9 +2525,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _suspended = suspend; - AMQFrame channelFlowFrame = - ChannelFlowBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion(), - !suspend); + ChannelFlowBody body = getMethodRegistry().createChannelFlowBody(!suspend); + + AMQFrame channelFlowFrame = body.generateFrame(_channelId); _connection.getProtocolHandler().syncWrite(channelFlowFrame, ChannelFlowOkBody.class); } @@ -2611,6 +2578,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi return _dirty; } + public void setTicket(int ticket) + { + _ticket = ticket; + } + /** Responsible for decoding a message fragment and passing it to the appropriate message consumer. */ private class Dispatcher extends Thread { @@ -2741,7 +2713,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _lock.wait(2000); } - if (message.getDeliverBody().deliveryTag <= _rollbackMark.get()) + if (message.getDeliverBody().getDeliveryTag() <= _rollbackMark.get()) { rejectMessage(message, true); } @@ -2798,7 +2770,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi if (message.getDeliverBody() != null) { final BasicMessageConsumer consumer = - (BasicMessageConsumer) _consumers.get(message.getDeliverBody().consumerTag); + (BasicMessageConsumer) _consumers.get(message.getDeliverBody().getConsumerTag()); if ((consumer == null) || consumer.isClosed()) { @@ -2807,14 +2779,14 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi if (consumer == null) { _dispatcherLogger.info("Dispatcher(" + dispatcherID + ")Received a message(" + System.identityHashCode(message) + ")" + "[" - + message.getDeliverBody().deliveryTag + "] from queue " - + message.getDeliverBody().consumerTag + " )without a handler - rejecting(requeue)..."); + + message.getDeliverBody().getDeliveryTag() + "] from queue " + + message.getDeliverBody().getConsumerTag() + " )without a handler - rejecting(requeue)..."); } else { - _dispatcherLogger.info("Dispatcher(" + dispatcherID + ")Received a message(" + System.identityHashCode(message) + ") [" - + message.getDeliverBody().deliveryTag + "] from queue consumer(" - + consumer.debugIdentity() + ") is closed rejecting(requeue)..."); + _dispatcherLogger.info("Received a message(" + System.identityHashCode(message) + ")" + "[" + + message.getDeliverBody().getDeliveryTag() + "] from queue " + " consumer(" + + consumer.debugIdentity() + ") is closed rejecting(requeue)..."); } } // Don't reject if we're already closing diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java index 319e728edf..e9f68fdc38 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQTopic.java @@ -96,8 +96,7 @@ public class AMQTopic extends AMQDestination implements Topic public boolean isNameRequired() { - // Topics always rely on a server generated queue name. - return false; + return !isDurable(); } /** @@ -112,4 +111,17 @@ public class AMQTopic extends AMQDestination implements Topic public void setQueueName(String queueName) { } + + public boolean equals(Object o) + { + return (o instanceof AMQTopic) + && ((AMQTopic)o).getExchangeName().equals(getExchangeName()) + && ((AMQTopic)o).getRoutingKey().equals(getRoutingKey()); + + } + + public int hashCode() + { + return getExchangeName().hashCode() + getRoutingKey().hashCode(); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java index 4f8a3e5557..ae31f5ebdd 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java @@ -514,11 +514,9 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer if (sendClose) { - // TODO: Be aware of possible changes to parameter order as versions change. - final AMQFrame cancelFrame = - BasicCancelBody.createAMQFrame(_channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), _consumerTag, // consumerTag - false); // nowait + BasicCancelBody body = getSession().getMethodRegistry().createBasicCancelBody(_consumerTag, false); + + final AMQFrame cancelFrame = body.generateFrame(_channelId); try { @@ -603,15 +601,15 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer if (debug) { - _logger.debug("notifyMessage called with message number " + messageFrame.getDeliverBody().deliveryTag); + _logger.debug("notifyMessage called with message number " + messageFrame.getDeliverBody().getDeliveryTag()); } try { AbstractJMSMessage jmsMessage = - _messageFactory.createMessage(messageFrame.getDeliverBody().deliveryTag, - messageFrame.getDeliverBody().redelivered, messageFrame.getDeliverBody().exchange, - messageFrame.getDeliverBody().routingKey, messageFrame.getContentHeader(), messageFrame.getBodies()); + _messageFactory.createMessage(messageFrame.getDeliverBody().getDeliveryTag(), + messageFrame.getDeliverBody().getRedelivered(), messageFrame.getDeliverBody().getExchange(), + messageFrame.getDeliverBody().getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies()); if (debug) { diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java index fb6e4aa9fd..7e96fb537c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java @@ -140,20 +140,20 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j private void declareDestination(AMQDestination destination) { + ExchangeDeclareBody body = getSession().getMethodRegistry().createExchangeDeclareBody(_session.getTicket(), + destination.getExchangeName(), + destination.getExchangeClass(), + false, + false, + false, + false, + true, + null); // Declare the exchange // Note that the durable and internal arguments are ignored since passive is set to false - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame declare = - ExchangeDeclareBody.createAMQFrame(_channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), null, // arguments - false, // autoDelete - false, // durable - destination.getExchangeName(), // exchange - false, // internal - true, // nowait - false, // passive - _session.getTicket(), // ticket - destination.getExchangeClass()); // type + + AMQFrame declare = body.generateFrame(_channelId); + _protocolHandler.writeFrame(declare); } @@ -478,16 +478,14 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j message.getJmsHeaders().setInteger(CustomJMSXProperty.JMS_QPID_DESTTYPE.getShortStringName(), type); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame publishFrame = - BasicPublishBody.createAMQFrame(_channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), destination.getExchangeName(), // exchange - immediate, // immediate - mandatory, // mandatory - destination.getRoutingKey(), // routingKey - _session.getTicket()); // ticket + + BasicPublishBody body = getSession().getMethodRegistry().createBasicPublishBody(_session.getTicket(), + destination.getExchangeName(), + destination.getRoutingKey(), + mandatory, + immediate); + + AMQFrame publishFrame = body.generateFrame(_channelId); message.prepareForSending(); ByteBuffer payload = message.getData(); @@ -525,13 +523,13 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j _logger.debug("Sending content body frames to " + destination); } - // weight argument of zero indicates no child content headers, just bodies - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. + + // TODO: This is a hacky way of getting the AMQP class-id for the Basic class + int classIfForBasic = getSession().getMethodRegistry().createBasicQosOkBody().getClazz(); + AMQFrame contentHeaderFrame = - ContentHeaderBody.createAMQFrame(_channelId, - BasicConsumeBody.getClazz(_protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion()), 0, contentHeaderProperties, size); + ContentHeaderBody.createAMQFrame(_channelId, + classIfForBasic, 0, contentHeaderProperties, size); if (_logger.isDebugEnabled()) { _logger.debug("Sending content header frame to " + destination); diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java new file mode 100644 index 0000000000..a150d1446a --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/AccessRequestOkMethodHandler.java @@ -0,0 +1,36 @@ +package org.apache.qpid.client.handler;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.framing.*;
+import org.apache.qpid.client.state.StateAwareMethodListener;
+import org.apache.qpid.client.state.AMQStateManager;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+import org.apache.qpid.client.AMQNoConsumersException;
+import org.apache.qpid.client.AMQNoRouteException;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQInvalidRoutingKeyException;
+import org.apache.qpid.AMQChannelClosedException;
+import org.apache.qpid.protocol.AMQConstant;
+
+public class AccessRequestOkMethodHandler implements StateAwareMethodListener<AccessRequestOkBody>
+{
+ private static final Logger _logger = LoggerFactory.getLogger(AccessRequestOkMethodHandler.class);
+
+ private static AccessRequestOkMethodHandler _handler = new AccessRequestOkMethodHandler();
+
+ public static AccessRequestOkMethodHandler getInstance()
+ {
+ return _handler;
+ }
+
+ public void methodReceived(AMQStateManager stateManager, AccessRequestOkBody method, int channelId)
+ throws AMQException
+ {
+ _logger.debug("AccessRequestOk method received");
+ final AMQProtocolSession session = stateManager.getProtocolSession();
+ session.setTicket(method.getTicket(), channelId);
+
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java index 8f0ee05b3e..e3e08667d8 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java @@ -25,12 +25,13 @@ import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.framing.BasicCancelOkBody; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BasicCancelOkMethodHandler implements StateAwareMethodListener +public class BasicCancelOkMethodHandler implements StateAwareMethodListener<BasicCancelOkBody> { private static final Logger _logger = LoggerFactory.getLogger(BasicCancelOkMethodHandler.class); @@ -44,16 +45,18 @@ public class BasicCancelOkMethodHandler implements StateAwareMethodListener private BasicCancelOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) + public void methodReceived(AMQStateManager stateManager, BasicCancelOkBody body, int channelId) throws AMQException { - BasicCancelOkBody body = (BasicCancelOkBody) evt.getMethod(); + AMQProtocolSession session = stateManager.getProtocolSession(); + + if (_logger.isInfoEnabled()) { - _logger.info("New BasicCancelOk method received for consumer:" + body.consumerTag); + _logger.info("New BasicCancelOk method received for consumer:" + body.getConsumerTag()); } - protocolSession.confirmConsumerCancelled(evt.getChannelId(), body.consumerTag); + session.confirmConsumerCancelled(channelId, body.getConsumerTag()); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java index 51120da55c..49c8a83833 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java @@ -31,7 +31,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BasicDeliverMethodHandler implements StateAwareMethodListener +public class BasicDeliverMethodHandler implements StateAwareMethodListener<BasicDeliverBody> { private static final Logger _logger = LoggerFactory.getLogger(BasicDeliverMethodHandler.class); @@ -42,11 +42,12 @@ public class BasicDeliverMethodHandler implements StateAwareMethodListener return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) + public void methodReceived(AMQStateManager stateManager, BasicDeliverBody body, int channelId) throws AMQException { - final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(), (BasicDeliverBody) evt.getMethod()); + final AMQProtocolSession session = stateManager.getProtocolSession(); + final UnprocessedMessage msg = new UnprocessedMessage(channelId, body); _logger.debug("New JmsDeliver method received"); - protocolSession.unprocessedMessageReceived(msg); + session.unprocessedMessageReceived(msg); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java index 0f00c6a26e..428d366f07 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java @@ -31,7 +31,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BasicReturnMethodHandler implements StateAwareMethodListener +public class BasicReturnMethodHandler implements StateAwareMethodListener<BasicReturnBody> { private static final Logger _logger = LoggerFactory.getLogger(BasicReturnMethodHandler.class); @@ -42,12 +42,15 @@ public class BasicReturnMethodHandler implements StateAwareMethodListener return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) +public void methodReceived(AMQStateManager stateManager, BasicReturnBody body, int channelId) throws AMQException { _logger.debug("New JmsBounce method received"); - final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(), (BasicReturnBody) evt.getMethod()); + final AMQProtocolSession session = stateManager.getProtocolSession(); + final UnprocessedMessage msg = new UnprocessedMessage(channelId, body); - protocolSession.unprocessedMessageReceived(msg); + session.unprocessedMessageReceived(msg); } + + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java index 139a32370e..8c8814e9b7 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java @@ -38,7 +38,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ChannelCloseMethodHandler implements StateAwareMethodListener +public class ChannelCloseMethodHandler implements StateAwareMethodListener<ChannelCloseBody> { private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseMethodHandler.class); @@ -49,22 +49,26 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener return _handler; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) + public void methodReceived(AMQStateManager stateManager, ChannelCloseBody method, int channelId) throws AMQException { _logger.debug("ChannelClose method received"); - ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); + final AMQProtocolSession session = stateManager.getProtocolSession(); - AMQConstant errorCode = AMQConstant.getConstant(method.replyCode); - AMQShortString reason = method.replyText; + + AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); + AMQShortString reason = method.getReplyText(); if (_logger.isDebugEnabled()) { _logger.debug("Channel close reply code: " + errorCode + ", reason: " + reason); } - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame frame = ChannelCloseOkBody.createAMQFrame(evt.getChannelId(), method.getMajor(), method.getMinor()); - protocolSession.writeFrame(frame); + + + ChannelCloseOkBody body = session.getMethodRegistry().createChannelCloseOkBody(); + AMQFrame frame = body.generateFrame(channelId); + session.writeFrame(frame); + if (errorCode != AMQConstant.REPLY_SUCCESS) { if (_logger.isDebugEnabled()) @@ -100,6 +104,6 @@ public class ChannelCloseMethodHandler implements StateAwareMethodListener } // fixme why is this only done when the close is expected... // should the above forced closes not also cause a close? - protocolSession.channelClosed(evt.getChannelId(), errorCode, String.valueOf(reason)); + session.channelClosed(channelId, errorCode, String.valueOf(reason)); } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java index e1fe2697e5..8d3277d4de 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java @@ -21,6 +21,7 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.ChannelCloseOkBody; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; @@ -29,7 +30,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ChannelCloseOkMethodHandler implements StateAwareMethodListener +public class ChannelCloseOkMethodHandler implements StateAwareMethodListener<ChannelCloseOkBody> { private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseOkMethodHandler.class); @@ -40,11 +41,12 @@ public class ChannelCloseOkMethodHandler implements StateAwareMethodListener return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) + public void methodReceived(AMQStateManager stateManager, ChannelCloseOkBody method, int channelId) throws AMQException { - _logger.info("Received channel-close-ok for channel-id " + evt.getChannelId()); + _logger.info("Received channel-close-ok for channel-id " + channelId); + final AMQProtocolSession session = stateManager.getProtocolSession(); // todo this should do the local closure } } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java index ca3f46d08b..96de8af54b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java @@ -30,7 +30,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ChannelFlowOkMethodHandler implements StateAwareMethodListener +public class ChannelFlowOkMethodHandler implements StateAwareMethodListener<ChannelFlowOkBody> { private static final Logger _logger = LoggerFactory.getLogger(ChannelFlowOkMethodHandler.class); private static final ChannelFlowOkMethodHandler _instance = new ChannelFlowOkMethodHandler(); @@ -43,10 +43,12 @@ public class ChannelFlowOkMethodHandler implements StateAwareMethodListener private ChannelFlowOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException + public void methodReceived(AMQStateManager stateManager, ChannelFlowOkBody body, int channelId) + throws AMQException { - ChannelFlowOkBody method = (ChannelFlowOkBody) evt.getMethod(); - _logger.debug("Received Channel.Flow-Ok message, active = " + method.active); + + _logger.debug("Received Channel.Flow-Ok message, active = " + body.getActive()); } + + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java new file mode 100644 index 0000000000..de976b05bd --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl.java @@ -0,0 +1,528 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.handler;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.qpid.framing.*;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.state.AMQStateManager;
+import org.apache.qpid.client.state.AMQMethodNotImplementedException;
+
+
+public class ClientMethodDispatcherImpl implements MethodDispatcher
+{
+
+
+ private static final BasicCancelOkMethodHandler _basicCancelOkMethodHandler = BasicCancelOkMethodHandler.getInstance();
+ private static final BasicDeliverMethodHandler _basicDeliverMethodHandler = BasicDeliverMethodHandler.getInstance();
+ private static final BasicReturnMethodHandler _basicReturnMethodHandler = BasicReturnMethodHandler.getInstance();
+ private static final ChannelCloseMethodHandler _channelCloseMethodHandler = ChannelCloseMethodHandler.getInstance();
+ private static final ChannelFlowOkMethodHandler _channelFlowOkMethodHandler = ChannelFlowOkMethodHandler.getInstance();
+ private static final ConnectionCloseMethodHandler _connectionCloseMethodHandler = ConnectionCloseMethodHandler.getInstance();
+ private static final ConnectionOpenOkMethodHandler _connectionOpenOkMethodHandler = ConnectionOpenOkMethodHandler.getInstance();
+ private static final ConnectionRedirectMethodHandler _connectionRedirectMethodHandler = ConnectionRedirectMethodHandler.getInstance();
+ private static final ConnectionSecureMethodHandler _connectionSecureMethodHandler = ConnectionSecureMethodHandler.getInstance();
+ private static final ConnectionStartMethodHandler _connectionStartMethodHandler = ConnectionStartMethodHandler.getInstance();
+ private static final ConnectionTuneMethodHandler _connectionTuneMethodHandler = ConnectionTuneMethodHandler.getInstance();
+ private static final ExchangeBoundOkMethodHandler _exchangeBoundOkMethodHandler = ExchangeBoundOkMethodHandler.getInstance();
+ private static final QueueDeleteOkMethodHandler _queueDeleteOkMethodHandler = QueueDeleteOkMethodHandler.getInstance();
+
+
+
+ private static interface DispatcherFactory
+ {
+ public ClientMethodDispatcherImpl createMethodDispatcher(AMQStateManager stateManager);
+ }
+
+ private static final Map<ProtocolVersion, DispatcherFactory> _dispatcherFactories =
+ new HashMap<ProtocolVersion, DispatcherFactory>();
+
+ static
+ {
+ _dispatcherFactories.put(ProtocolVersion.v8_0,
+ new DispatcherFactory()
+ {
+ public ClientMethodDispatcherImpl createMethodDispatcher(AMQStateManager stateManager)
+ {
+ return new ClientMethodDispatcherImpl_8_0(stateManager);
+ }
+ });
+
+ _dispatcherFactories.put(ProtocolVersion.v0_9,
+ new DispatcherFactory()
+ {
+ public ClientMethodDispatcherImpl createMethodDispatcher(AMQStateManager stateManager)
+ {
+ return new ClientMethodDispatcherImpl_0_9(stateManager);
+ }
+ });
+
+ }
+
+
+ public static ClientMethodDispatcherImpl newMethodDispatcher(ProtocolVersion version, AMQStateManager stateManager)
+ {
+ DispatcherFactory factory = _dispatcherFactories.get(version);
+ return factory.createMethodDispatcher(stateManager);
+ }
+
+
+
+
+ private AMQStateManager _stateManager;
+
+ public ClientMethodDispatcherImpl(AMQStateManager stateManager)
+ {
+ _stateManager = stateManager;
+ }
+
+
+ public AMQStateManager getStateManager()
+ {
+ return _stateManager;
+ }
+
+ public boolean dispatchAccessRequestOk(AccessRequestOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchBasicCancelOk(BasicCancelOkBody body, int channelId) throws AMQException
+ {
+ _basicCancelOkMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicConsumeOk(BasicConsumeOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchBasicDeliver(BasicDeliverBody body, int channelId) throws AMQException
+ {
+ _basicDeliverMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchBasicGetEmpty(BasicGetEmptyBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchBasicGetOk(BasicGetOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchBasicQosOk(BasicQosOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchBasicReturn(BasicReturnBody body, int channelId) throws AMQException
+ {
+ _basicReturnMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchChannelClose(ChannelCloseBody body, int channelId) throws AMQException
+ {
+ _channelCloseMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchChannelCloseOk(ChannelCloseOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelFlow(ChannelFlowBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelFlowOk(ChannelFlowOkBody body, int channelId) throws AMQException
+ {
+ _channelFlowOkMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchChannelOpenOk(ChannelOpenOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchConnectionClose(ConnectionCloseBody body, int channelId) throws AMQException
+ {
+ _connectionCloseMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionCloseOk(ConnectionCloseOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchConnectionOpenOk(ConnectionOpenOkBody body, int channelId) throws AMQException
+ {
+ _connectionOpenOkMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionRedirect(ConnectionRedirectBody body, int channelId) throws AMQException
+ {
+ _connectionRedirectMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionSecure(ConnectionSecureBody body, int channelId) throws AMQException
+ {
+ _connectionSecureMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionStart(ConnectionStartBody body, int channelId) throws AMQException
+ {
+ _connectionStartMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchConnectionTune(ConnectionTuneBody body, int channelId) throws AMQException
+ {
+ _connectionTuneMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchQueueDeleteOk(QueueDeleteOkBody body, int channelId) throws AMQException
+ {
+ _queueDeleteOkMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchQueuePurgeOk(QueuePurgeOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchStreamCancelOk(StreamCancelOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchStreamConsumeOk(StreamConsumeOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchAccessRequest(AccessRequestBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicAck(BasicAckBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicCancel(BasicCancelBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicConsume(BasicConsumeBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicGet(BasicGetBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicPublish(BasicPublishBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicQos(BasicQosBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicRecover(BasicRecoverBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchBasicReject(BasicRejectBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchChannelOpen(ChannelOpenBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchConnectionOpen(ConnectionOpenBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchConnectionSecureOk(ConnectionSecureOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchConnectionStartOk(ConnectionStartOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchConnectionTuneOk(ConnectionTuneOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchDtxSelect(DtxSelectBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchDtxStart(DtxStartBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchExchangeBound(ExchangeBoundBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchExchangeDeclare(ExchangeDeclareBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchExchangeDelete(ExchangeDeleteBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileAck(FileAckBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileCancel(FileCancelBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileConsume(FileConsumeBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFilePublish(FilePublishBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileQos(FileQosBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileReject(FileRejectBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchQueueBind(QueueBindBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchQueueDeclare(QueueDeclareBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchQueueDelete(QueueDeleteBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchQueuePurge(QueuePurgeBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchStreamCancel(StreamCancelBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchStreamConsume(StreamConsumeBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchStreamPublish(StreamPublishBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchStreamQos(StreamQosBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchTunnelRequest(TunnelRequestBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchTxCommit(TxCommitBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchTxRollback(TxRollbackBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchTxSelect(TxSelectBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchDtxSelectOk(DtxSelectOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchDtxStartOk(DtxStartOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchExchangeBoundOk(ExchangeBoundOkBody body, int channelId) throws AMQException
+ {
+ _exchangeBoundOkMethodHandler.methodReceived(_stateManager,body,channelId);
+ return true;
+ }
+
+ public boolean dispatchExchangeDeclareOk(ExchangeDeclareOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchExchangeDeleteOk(ExchangeDeleteOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchFileCancelOk(FileCancelOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileConsumeOk(FileConsumeOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileDeliver(FileDeliverBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileOpen(FileOpenBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileOpenOk(FileOpenOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileQosOk(FileQosOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileReturn(FileReturnBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchFileStage(FileStageBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchQueueBindOk(QueueBindOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchQueueDeclareOk(QueueDeclareOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchStreamDeliver(StreamDeliverBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchStreamQosOk(StreamQosOkBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchStreamReturn(StreamReturnBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchTxCommitOk(TxCommitOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTxRollbackOk(TxRollbackOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTxSelectOk(TxSelectOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java new file mode 100644 index 0000000000..ae6d5e8283 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_0_9.java @@ -0,0 +1,155 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.handler;
+
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.amqp_0_9.MethodDispatcher_0_9;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.state.AMQStateManager;
+import org.apache.qpid.client.state.AMQMethodNotImplementedException;
+
+
+public class ClientMethodDispatcherImpl_0_9 extends ClientMethodDispatcherImpl implements MethodDispatcher_0_9
+{
+ public ClientMethodDispatcherImpl_0_9(AMQStateManager stateManager)
+ {
+ super(stateManager);
+ }
+
+
+ public boolean dispatchBasicRecoverSyncOk(BasicRecoverSyncOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchBasicRecoverSync(BasicRecoverSyncBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchChannelOk(ChannelOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelPing(ChannelPingBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelPong(ChannelPongBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelResume(ChannelResumeBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchMessageAppend(MessageAppendBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageCancel(MessageCancelBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchMessageCheckpoint(MessageCheckpointBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageClose(MessageCloseBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageConsume(MessageConsumeBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchMessageEmpty(MessageEmptyBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageGet(MessageGetBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchMessageOffset(MessageOffsetBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageOk(MessageOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageOpen(MessageOpenBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageQos(MessageQosBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchMessageRecover(MessageRecoverBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchMessageReject(MessageRejectBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageResume(MessageResumeBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchMessageTransfer(MessageTransferBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchQueueUnbind(QueueUnbindBody body, int channelId) throws AMQException
+ {
+ throw new AMQMethodNotImplementedException(body);
+ }
+
+ public boolean dispatchQueueUnbindOk(QueueUnbindOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java new file mode 100644 index 0000000000..c28720f370 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ClientMethodDispatcherImpl_8_0.java @@ -0,0 +1,65 @@ +package org.apache.qpid.client.handler;
+
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.amqp_8_0.MethodDispatcher_8_0;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.client.state.AMQStateManager;
+
+public class ClientMethodDispatcherImpl_8_0 extends ClientMethodDispatcherImpl implements MethodDispatcher_8_0
+{
+ public ClientMethodDispatcherImpl_8_0(AMQStateManager stateManager)
+ {
+ super(stateManager);
+ }
+
+ public boolean dispatchBasicRecoverOk(BasicRecoverOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchChannelAlert(ChannelAlertBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestContent(TestContentBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestContentOk(TestContentOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestInteger(TestIntegerBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestIntegerOk(TestIntegerOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestString(TestStringBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestStringOk(TestStringOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestTable(TestTableBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+
+ public boolean dispatchTestTableOk(TestTableOkBody body, int channelId) throws AMQException
+ {
+ return false;
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java index df096d3c4e..4d805cf123 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java @@ -36,7 +36,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ConnectionCloseMethodHandler implements StateAwareMethodListener +public class ConnectionCloseMethodHandler implements StateAwareMethodListener<ConnectionCloseBody> { private static final Logger _logger = LoggerFactory.getLogger(ConnectionCloseMethodHandler.class); @@ -50,24 +50,26 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener private ConnectionCloseMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionCloseBody method, int channelId) + throws AMQException { _logger.info("ConnectionClose frame received"); - ConnectionCloseBody method = (ConnectionCloseBody) evt.getMethod(); + final AMQProtocolSession session = stateManager.getProtocolSession(); + // does it matter // stateManager.changeState(AMQState.CONNECTION_CLOSING); - AMQConstant errorCode = AMQConstant.getConstant(method.replyCode); - AMQShortString reason = method.replyText; + AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); + AMQShortString reason = method.getReplyText(); try { + + ConnectionCloseOkBody closeOkBody = session.getMethodRegistry().createConnectionCloseOkBody(); // TODO: check whether channel id of zero is appropriate // Be aware of possible changes to parameter order as versions change. - protocolSession.writeFrame(ConnectionCloseOkBody.createAMQFrame((short) 0, method.getMajor(), - method.getMinor())); + session.writeFrame(closeOkBody.generateFrame(0)); if (errorCode != AMQConstant.REPLY_SUCCESS) { @@ -75,7 +77,7 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener { _logger.info("Authentication Error:" + Thread.currentThread().getName()); - protocolSession.closeProtocolSession(); + session.closeProtocolSession(); // todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state. stateManager.changeState(AMQState.CONNECTION_NOT_STARTED); @@ -94,9 +96,11 @@ public class ConnectionCloseMethodHandler implements StateAwareMethodListener { // this actually closes the connection in the case where it is not an error. - protocolSession.closeProtocolSession(); + session.closeProtocolSession(); stateManager.changeState(AMQState.CONNECTION_CLOSED); } } + + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java index 2e0f273c32..fd7acac84f 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java @@ -21,13 +21,14 @@ package org.apache.qpid.client.handler; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.ConnectionOpenOkBody; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; import org.apache.qpid.protocol.AMQMethodEvent; -public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener +public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener<ConnectionOpenOkBody> { private static final ConnectionOpenOkMethodHandler _instance = new ConnectionOpenOkMethodHandler(); @@ -40,9 +41,11 @@ public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionOpenOkBody body, int channelId) + throws AMQException { stateManager.changeState(AMQState.CONNECTION_OPEN); } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java index 213c0eba6e..cac68c9467 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java @@ -30,7 +30,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ConnectionRedirectMethodHandler implements StateAwareMethodListener +public class ConnectionRedirectMethodHandler implements StateAwareMethodListener<ConnectionRedirectBody> { private static final Logger _logger = LoggerFactory.getLogger(ConnectionRedirectMethodHandler.class); @@ -46,13 +46,13 @@ public class ConnectionRedirectMethodHandler implements StateAwareMethodListener private ConnectionRedirectMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionRedirectBody method, int channelId) + throws AMQException { _logger.info("ConnectionRedirect frame received"); - ConnectionRedirectBody method = (ConnectionRedirectBody) evt.getMethod(); + final AMQProtocolSession session = stateManager.getProtocolSession(); - String host = method.host.toString(); + String host = method.getHost().toString(); // the host is in the form hostname:port with the port being optional int portIndex = host.indexOf(':'); @@ -68,6 +68,7 @@ public class ConnectionRedirectMethodHandler implements StateAwareMethodListener } - protocolSession.failover(host, port); + session.failover(host, port); } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java index ab6acffeaf..ab6d4b1b92 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java @@ -32,7 +32,7 @@ import org.apache.qpid.framing.ConnectionSecureBody; import org.apache.qpid.framing.ConnectionSecureOkBody; import org.apache.qpid.protocol.AMQMethodEvent; -public class ConnectionSecureMethodHandler implements StateAwareMethodListener +public class ConnectionSecureMethodHandler implements StateAwareMethodListener<ConnectionSecureBody> { private static final ConnectionSecureMethodHandler _instance = new ConnectionSecureMethodHandler(); @@ -41,27 +41,26 @@ public class ConnectionSecureMethodHandler implements StateAwareMethodListener return _instance; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionSecureBody body, int channelId) + throws AMQException { - SaslClient client = protocolSession.getSaslClient(); + final AMQProtocolSession session = stateManager.getProtocolSession(); + SaslClient client = session.getSaslClient(); if (client == null) { throw new AMQException("No SASL client set up - cannot proceed with authentication"); } - ConnectionSecureBody body = (ConnectionSecureBody) evt.getMethod(); + try { // Evaluate server challenge - byte[] response = client.evaluateChallenge(body.challenge); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame responseFrame = ConnectionSecureOkBody.createAMQFrame(evt.getChannelId(), - body.getMajor(), body.getMinor(), - response); // response - protocolSession.writeFrame(responseFrame); + byte[] response = client.evaluateChallenge(body.getChallenge()); + + ConnectionSecureOkBody secureOkBody = session.getMethodRegistry().createConnectionSecureOkBody(response); + + session.writeFrame(secureOkBody.generateFrame(channelId)); } catch (SaslException e) { @@ -70,4 +69,6 @@ public class ConnectionSecureMethodHandler implements StateAwareMethodListener } + + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java index f14e256172..4c755fb68c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java @@ -48,7 +48,7 @@ import java.io.UnsupportedEncodingException; import java.util.HashSet; import java.util.StringTokenizer; -public class ConnectionStartMethodHandler implements StateAwareMethodListener +public class ConnectionStartMethodHandler implements StateAwareMethodListener<ConnectionStartBody> { private static final Logger _log = LoggerFactory.getLogger(ConnectionStartMethodHandler.class); @@ -62,15 +62,16 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener private ConnectionStartMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionStartBody body, int channelId) + throws AMQException { _log.debug("public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, " + "AMQMethodEvent evt): called"); - ConnectionStartBody body = (ConnectionStartBody) evt.getMethod(); + final AMQProtocolSession session = stateManager.getProtocolSession(); + - ProtocolVersion pv = new ProtocolVersion((byte) body.versionMajor, (byte) body.versionMinor); + ProtocolVersion pv = new ProtocolVersion((byte) body.getVersionMajor(), (byte) body.getVersionMinor()); // For the purposes of interop, we can make the client accept the broker's version string. // If it does, it then internally records the version as being the latest one that it understands. @@ -83,26 +84,26 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener if (pv.isSupported()) { - protocolSession.setProtocolVersion(pv.getMajorVersion(), pv.getMinorVersion()); + session.setProtocolVersion(pv); try { // Used to hold the SASL mechanism to authenticate with. String mechanism; - if (body.mechanisms == null) + if (body.getMechanisms()== null) { throw new AMQException("mechanism not specified in ConnectionStart method frame"); } else { - mechanism = chooseMechanism(body.mechanisms); + mechanism = chooseMechanism(body.getMechanisms()); _log.debug("mechanism = " + mechanism); } if (mechanism == null) { - throw new AMQException("No supported security mechanism found, passed: " + new String(body.mechanisms)); + throw new AMQException("No supported security mechanism found, passed: " + new String(body.getMechanisms())); } byte[] saslResponse; @@ -110,7 +111,7 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener { SaslClient sc = Sasl.createSaslClient(new String[] { mechanism }, null, "AMQP", "localhost", null, - createCallbackHandler(mechanism, protocolSession)); + createCallbackHandler(mechanism, session)); if (sc == null) { throw new AMQException( @@ -119,21 +120,21 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener + " details of how to register non-standard SASL client providers."); } - protocolSession.setSaslClient(sc); + session.setSaslClient(sc); saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); } catch (SaslException e) { - protocolSession.setSaslClient(null); + session.setSaslClient(null); throw new AMQException("Unable to create SASL client: " + e, e); } - if (body.locales == null) + if (body.getLocales() == null) { throw new AMQException("Locales is not defined in Connection Start method"); } - final String locales = new String(body.locales, "utf8"); + final String locales = new String(body.getLocales(), "utf8"); final StringTokenizer tokenizer = new StringTokenizer(locales, " "); String selectedLocale = null; if (tokenizer.hasMoreTokens()) @@ -149,23 +150,20 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener FieldTable clientProperties = FieldTableFactory.newFieldTable(); clientProperties.setString(new AMQShortString(ClientProperties.instance.toString()), - protocolSession.getClientID()); + session.getClientID()); clientProperties.setString(new AMQShortString(ClientProperties.product.toString()), QpidProperties.getProductName()); clientProperties.setString(new AMQShortString(ClientProperties.version.toString()), QpidProperties.getReleaseVersion()); clientProperties.setString(new AMQShortString(ClientProperties.platform.toString()), getFullSystemInfo()); + + ConnectionStartOkBody connectionStartOkBody = session.getMethodRegistry().createConnectionStartOkBody(clientProperties,new AMQShortString(mechanism),saslResponse,new AMQShortString(locales)); // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. - protocolSession.writeFrame(ConnectionStartOkBody.createAMQFrame(evt.getChannelId(), - protocolSession.getProtocolMajorVersion(), protocolSession.getProtocolMinorVersion(), - clientProperties, // clientProperties - new AMQShortString(selectedLocale), // locale - new AMQShortString(mechanism), // mechanism - saslResponse)); // response - + session.writeFrame(connectionStartOkBody.generateFrame(channelId)); + } catch (UnsupportedEncodingException e) { @@ -174,10 +172,10 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener } else { - _log.error("Broker requested Protocol [" + body.versionMajor + "-" + body.versionMinor + _log.error("Broker requested Protocol [" + body.getVersionMajor() + "-" + body.getVersionMinor() + "] which is not supported by this version of the client library"); - protocolSession.closeProtocolSession(); + session.closeProtocolSession(); } } @@ -236,4 +234,5 @@ public class ConnectionStartMethodHandler implements StateAwareMethodListener throw new AMQException("Unable to create callback handler: " + e, e); } } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java index 68556991d7..fc0e40b745 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java @@ -26,17 +26,13 @@ import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionOpenBody; -import org.apache.qpid.framing.ConnectionTuneBody; -import org.apache.qpid.framing.ConnectionTuneOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ConnectionTuneMethodHandler implements StateAwareMethodListener +public class ConnectionTuneMethodHandler implements StateAwareMethodListener<ConnectionTuneBody> { private static final Logger _logger = LoggerFactory.getLogger(ConnectionTuneMethodHandler.class); @@ -50,48 +46,41 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener protected ConnectionTuneMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException + public void methodReceived(AMQStateManager stateManager, ConnectionTuneBody frame, int channelId) + throws AMQException { _logger.debug("ConnectionTune frame received"); - ConnectionTuneBody frame = (ConnectionTuneBody) evt.getMethod(); + final AMQProtocolSession session = stateManager.getProtocolSession(); + final MethodRegistry methodRegistry = session.getMethodRegistry(); - ConnectionTuneParameters params = protocolSession.getConnectionTuneParameters(); + + ConnectionTuneParameters params = session.getConnectionTuneParameters(); if (params == null) { params = new ConnectionTuneParameters(); } - params.setFrameMax(frame.frameMax); - params.setChannelMax(frame.channelMax); - params.setHeartbeat(Integer.getInteger("amqj.heartbeat.delay", frame.heartbeat)); - protocolSession.setConnectionTuneParameters(params); + params.setFrameMax(frame.getFrameMax()); + params.setChannelMax(frame.getChannelMax()); + params.setHeartbeat(Integer.getInteger("amqj.heartbeat.delay", frame.getHeartbeat())); + session.setConnectionTuneParameters(params); stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); - protocolSession.writeFrame(createTuneOkFrame(evt.getChannelId(), params, frame.getMajor(), frame.getMinor())); - String host = protocolSession.getAMQConnection().getVirtualHost(); + ConnectionTuneOkBody tuneOkBody = methodRegistry.createConnectionTuneOkBody(params.getChannelMax(), + params.getFrameMax(), + params.getHeartbeat()); + // Be aware of possible changes to parameter order as versions change. + session.writeFrame(tuneOkBody.generateFrame(channelId)); + + String host = session.getAMQConnection().getVirtualHost(); AMQShortString virtualHost = new AMQShortString("/" + host); - protocolSession.writeFrame(createConnectionOpenFrame(evt.getChannelId(), virtualHost, null, true, frame.getMajor(), - frame.getMinor())); - } + ConnectionOpenBody openBody = methodRegistry.createConnectionOpenBody(virtualHost,null,true); - protected AMQFrame createConnectionOpenFrame(int channel, AMQShortString path, AMQShortString capabilities, - boolean insist, byte major, byte minor) - { // Be aware of possible changes to parameter order as versions change. - return ConnectionOpenBody.createAMQFrame(channel, major, minor, // AMQP version (major, minor) - capabilities, // capabilities - insist, // insist - path); // virtualHost + session.writeFrame(openBody.generateFrame(channelId)); } - protected AMQFrame createTuneOkFrame(int channel, ConnectionTuneParameters params, byte major, byte minor) - { - // Be aware of possible changes to parameter order as versions change. - return ConnectionTuneOkBody.createAMQFrame(channel, major, minor, params.getChannelMax(), // channelMax - params.getFrameMax(), // frameMax - params.getHeartbeat()); // heartbeat - } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java index 862a9be8d4..8de40beb10 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java @@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory; /** * @author Apache Software Foundation */ -public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener +public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener<ExchangeBoundOkBody> { private static final Logger _logger = LoggerFactory.getLogger(ExchangeBoundOkMethodHandler.class); private static final ExchangeBoundOkMethodHandler _instance = new ExchangeBoundOkMethodHandler(); @@ -46,14 +46,14 @@ public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener private ExchangeBoundOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException + public void methodReceived(AMQStateManager stateManager, ExchangeBoundOkBody body, int channelId) + throws AMQException { if (_logger.isDebugEnabled()) { - ExchangeBoundOkBody body = (ExchangeBoundOkBody) evt.getMethod(); - _logger.debug("Received Exchange.Bound-Ok message, response code: " + body.replyCode + " text: " - + body.replyText); + _logger.debug("Received Exchange.Bound-Ok message, response code: " + body.getReplyCode() + " text: " + + body.getReplyText()); } } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java index 65060d44d2..41225c0569 100644 --- a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java @@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory; /** * @author Apache Software Foundation */ -public class QueueDeleteOkMethodHandler implements StateAwareMethodListener +public class QueueDeleteOkMethodHandler implements StateAwareMethodListener<QueueDeleteOkBody> { private static final Logger _logger = LoggerFactory.getLogger(QueueDeleteOkMethodHandler.class); private static final QueueDeleteOkMethodHandler _instance = new QueueDeleteOkMethodHandler(); @@ -46,13 +46,14 @@ public class QueueDeleteOkMethodHandler implements StateAwareMethodListener private QueueDeleteOkMethodHandler() { } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException - { + public void methodReceived(AMQStateManager stateManager, QueueDeleteOkBody body, int channelId) + throws AMQException + { if (_logger.isDebugEnabled()) { - QueueDeleteOkBody body = (QueueDeleteOkBody) evt.getMethod(); - _logger.debug("Received Queue.Delete-Ok message, message count: " + body.messageCount); + _logger.debug("Received Queue.Delete-Ok message, message count: " + body.getMessageCount()); } } + + } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java index 19142067cb..56efec4fa2 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java @@ -41,16 +41,7 @@ import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.AMQBody; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.HeartbeatBody; +import org.apache.qpid.framing.*; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; @@ -618,16 +609,11 @@ public class AMQProtocolHandler extends IoHandlerAdapter { getStateManager().changeState(AMQState.CONNECTION_CLOSING); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame frame = - ConnectionCloseBody.createAMQFrame(0, _protocolSession.getProtocolMajorVersion(), - _protocolSession.getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - new AMQShortString("JMS client is closing the connection.")); // replyText + ConnectionCloseBody body = _protocolSession.getMethodRegistry().createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), // replyCode + new AMQShortString("JMS client is closing the connection."),0,0); + + + final AMQFrame frame = body.generateFrame(0); try { @@ -730,4 +716,14 @@ public class AMQProtocolHandler extends IoHandlerAdapter { return _protocolSession.getProtocolMinorVersion(); } + + public MethodRegistry getMethodRegistry() + { + return getStateManager().getMethodRegistry(); + } + + public ProtocolVersion getProtocolVersion() + { + return _protocolSession.getProtocolVersion(); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java index 5fe6ffe6c6..18c1e85eaa 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java @@ -20,40 +20,29 @@ */ package org.apache.qpid.client.protocol; -import org.apache.commons.lang.StringUtils; - import org.apache.mina.common.CloseFuture; import org.apache.mina.common.IdleStatus; import org.apache.mina.common.IoSession; import org.apache.mina.common.WriteFuture; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jms.JMSException; +import javax.security.sasl.SaslClient; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import org.apache.qpid.AMQException; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQSession; import org.apache.qpid.client.ConnectionTuneParameters; -// import org.apache.qpid.client.message.UnexpectedBodyReceivedException; import org.apache.qpid.client.message.UnprocessedMessage; import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.MainRegistry; -import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersion; -import org.apache.qpid.framing.VersionSpecificRegistry; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.jms.JMSException; -import javax.security.sasl.SaslClient; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.UUID; +import org.apache.qpid.client.handler.ClientMethodDispatcherImpl; /** * Wrapper for protocol session that provides type-safe access to session attributes. <p/> The underlying protocol @@ -100,12 +89,19 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession protected int _queueId = 1; protected final Object _queueIdLock = new Object(); - private byte _protocolMinorVersion; - private byte _protocolMajorVersion; - private VersionSpecificRegistry _registry = - MainRegistry.getVersionSpecificRegistry(ProtocolVersion.getLatestSupportedVersion()); + private ProtocolVersion _protocolVersion; +// private VersionSpecificRegistry _registry = +// MainRegistry.getVersionSpecificRegistry(ProtocolVersion.getLatestSupportedVersion()); + - private final AMQConnection _connection; + private MethodRegistry _methodRegistry = + MethodRegistry.getMethodRegistry(ProtocolVersion.getLatestSupportedVersion()); + + + private MethodDispatcher _methodDispatcher; + + + private final AMQConnection _connection; public AMQProtocolSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection) { @@ -125,6 +121,9 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession _minaProtocolSession.setWriteTimeout(LAST_WRITE_FUTURE_JOIN_TIMEOUT); _stateManager = stateManager; _stateManager.setProtocolSession(this); + _protocolVersion = ProtocolVersion.getLatestSupportedVersion(); + _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(ProtocolVersion.getLatestSupportedVersion(), + stateManager); _connection = connection; } @@ -163,6 +162,8 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession public void setStateManager(AMQStateManager stateManager) { _stateManager = stateManager; + _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(_protocolVersion, + stateManager); } public String getVirtualHost() @@ -434,26 +435,55 @@ public class AMQProtocolSession implements AMQVersionAwareProtocolSession session.confirmConsumerCancelled(consumerTag); } - public void setProtocolVersion(final byte versionMajor, final byte versionMinor) + public void setProtocolVersion(final ProtocolVersion pv) { - _protocolMajorVersion = versionMajor; - _protocolMinorVersion = versionMinor; - _registry = MainRegistry.getVersionSpecificRegistry(versionMajor, versionMinor); + _protocolVersion = pv; + _methodRegistry = MethodRegistry.getMethodRegistry(pv); + _methodDispatcher = ClientMethodDispatcherImpl.newMethodDispatcher(pv, _stateManager); + + // _registry = MainRegistry.getVersionSpecificRegistry(versionMajor, versionMinor); } public byte getProtocolMinorVersion() { - return _protocolMinorVersion; + return _protocolVersion.getMinorVersion(); } public byte getProtocolMajorVersion() { - return _protocolMajorVersion; + return _protocolVersion.getMajorVersion(); + } + + public ProtocolVersion getProtocolVersion() + { + return _protocolVersion; + } + +// public VersionSpecificRegistry getRegistry() +// { +// return _registry; +// } + + public MethodRegistry getMethodRegistry() + { + return _methodRegistry; + } + + public MethodDispatcher getMethodDispatcher() + { + return _methodDispatcher; } - public VersionSpecificRegistry getRegistry() + + public void setTicket(int ticket, int channelId) { - return _registry; + final AMQSession session = getSession(channelId); + session.setTicket(ticket); } + + public void setMethodDispatcher(MethodDispatcher methodDispatcher) + { + _methodDispatcher = methodDispatcher; + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/AMQMethodNotImplementedException.java b/java/client/src/main/java/org/apache/qpid/client/state/AMQMethodNotImplementedException.java new file mode 100644 index 0000000000..767bcfcbcd --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/state/AMQMethodNotImplementedException.java @@ -0,0 +1,32 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.client.state;
+
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.AMQException;
+
+public class AMQMethodNotImplementedException extends AMQException
+{
+ public AMQMethodNotImplementedException(AMQMethodBody body)
+ {
+ super("Unexpected Method Received: " + body.getClass().getName());
+ }
+}
diff --git a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java index 72ff3844ca..a9473df08c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java @@ -21,43 +21,15 @@ package org.apache.qpid.client.state; import org.apache.qpid.AMQException; -import org.apache.qpid.client.handler.BasicCancelOkMethodHandler; -import org.apache.qpid.client.handler.BasicDeliverMethodHandler; -import org.apache.qpid.client.handler.BasicReturnMethodHandler; -import org.apache.qpid.client.handler.ChannelCloseMethodHandler; -import org.apache.qpid.client.handler.ChannelCloseOkMethodHandler; -import org.apache.qpid.client.handler.ChannelFlowOkMethodHandler; -import org.apache.qpid.client.handler.ConnectionCloseMethodHandler; -import org.apache.qpid.client.handler.ConnectionOpenOkMethodHandler; -import org.apache.qpid.client.handler.ConnectionSecureMethodHandler; -import org.apache.qpid.client.handler.ConnectionStartMethodHandler; -import org.apache.qpid.client.handler.ConnectionTuneMethodHandler; -import org.apache.qpid.client.handler.ExchangeBoundOkMethodHandler; -import org.apache.qpid.client.handler.QueueDeleteOkMethodHandler; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.BasicCancelOkBody; -import org.apache.qpid.framing.BasicDeliverBody; -import org.apache.qpid.framing.BasicReturnBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelFlowOkBody; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionOpenOkBody; -import org.apache.qpid.framing.ConnectionSecureBody; -import org.apache.qpid.framing.ConnectionStartBody; -import org.apache.qpid.framing.ConnectionTuneBody; -import org.apache.qpid.framing.ExchangeBoundOkBody; -import org.apache.qpid.framing.QueueDeleteOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; import java.util.Iterator; -import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; /** @@ -73,11 +45,11 @@ public class AMQStateManager implements AMQMethodListener /** The current state */ private AMQState _currentState; + /** * Maps from an AMQState instance to a Map from Class to StateTransitionHandler. The class must be a subclass of * AMQFrame. */ - protected final Map _state2HandlersMap = new HashMap(); private final CopyOnWriteArraySet _stateListeners = new CopyOnWriteArraySet(); private final Object _stateLock = new Object(); @@ -97,53 +69,10 @@ public class AMQStateManager implements AMQMethodListener { _protocolSession = protocolSession; _currentState = state; - if (register) - { - registerListeners(); - } - } - protected void registerListeners() - { - Map frame2handlerMap = new HashMap(); - - // we need to register a map for the null (i.e. all state) handlers otherwise you get - // a stack overflow in the handler searching code when you present it with a frame for which - // no handlers are registered - // - _state2HandlersMap.put(null, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionStartBody.class, ConnectionStartMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_STARTED, frame2handlerMap); + } - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionTuneBody.class, ConnectionTuneMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionSecureBody.class, ConnectionSecureMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_TUNED, frame2handlerMap); - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionOpenOkBody.class, ConnectionOpenOkMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_OPENED, frame2handlerMap); - - // - // ConnectionOpen handlers - // - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ChannelCloseBody.class, ChannelCloseMethodHandler.getInstance()); - frame2handlerMap.put(ChannelCloseOkBody.class, ChannelCloseOkMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - frame2handlerMap.put(BasicDeliverBody.class, BasicDeliverMethodHandler.getInstance()); - frame2handlerMap.put(BasicReturnBody.class, BasicReturnMethodHandler.getInstance()); - frame2handlerMap.put(BasicCancelOkBody.class, BasicCancelOkMethodHandler.getInstance()); - frame2handlerMap.put(ChannelFlowOkBody.class, ChannelFlowOkMethodHandler.getInstance()); - frame2handlerMap.put(QueueDeleteOkBody.class, QueueDeleteOkMethodHandler.getInstance()); - frame2handlerMap.put(ExchangeBoundOkBody.class, ExchangeBoundOkMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_OPEN, frame2handlerMap); - } public AMQState getCurrentState() { @@ -177,56 +106,14 @@ public class AMQStateManager implements AMQMethodListener public <B extends AMQMethodBody> boolean methodReceived(AMQMethodEvent<B> evt) throws AMQException { - StateAwareMethodListener handler = findStateTransitionHandler(_currentState, evt.getMethod()); - if (handler != null) - { - handler.methodReceived(this, _protocolSession, evt); - - return true; - } - return false; + B method = evt.getMethod(); + + // StateAwareMethodListener handler = findStateTransitionHandler(_currentState, evt.getMethod()); + method.execute(_protocolSession.getMethodDispatcher(), evt.getChannelId()); + return true; } - protected StateAwareMethodListener findStateTransitionHandler(AMQState currentState, AMQMethodBody frame) - // throws IllegalStateTransitionException - { - final Class clazz = frame.getClass(); - if (_logger.isDebugEnabled()) - { - _logger.debug("Looking for state[" + currentState + "] transition handler for frame " + clazz); - } - - final Map classToHandlerMap = (Map) _state2HandlersMap.get(currentState); - - if (classToHandlerMap == null) - { - // if no specialised per state handler is registered look for a - // handler registered for "all" states - return findStateTransitionHandler(null, frame); - } - - final StateAwareMethodListener handler = (StateAwareMethodListener) classToHandlerMap.get(clazz); - if (handler == null) - { - if (currentState == null) - { - _logger.debug("No state transition handler defined for receiving frame " + frame); - - return null; - } - else - { - // if no specialised per state handler is registered look for a - // handler registered for "all" states - return findStateTransitionHandler(null, frame); - } - } - else - { - return handler; - } - } public void attainState(final AMQState s) throws AMQException { @@ -273,4 +160,9 @@ public class AMQStateManager implements AMQMethodListener { _protocolSession = session; } + + public MethodRegistry getMethodRegistry() + { + return getProtocolSession().getMethodRegistry(); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java b/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java index b3932533ce..8c65f56af3 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java @@ -21,6 +21,7 @@ package org.apache.qpid.client.state; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.protocol.AMQMethodEvent; @@ -29,8 +30,9 @@ import org.apache.qpid.protocol.AMQMethodEvent; * the opportunity to update state. * */ -public interface StateAwareMethodListener +public interface StateAwareMethodListener<B extends AMQMethodBody> { - void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, - AMQMethodEvent evt) throws AMQException; + + void methodReceived(AMQStateManager stateManager, B body, int channelId) throws AMQException; + } diff --git a/java/client/src/test/java/org/apache/qpid/client/SpecificMethodFrameListenerTest.java b/java/client/src/test/java/org/apache/qpid/client/SpecificMethodFrameListenerTest.java index 4cffcecf8a..69684a81ea 100644 --- a/java/client/src/test/java/org/apache/qpid/client/SpecificMethodFrameListenerTest.java +++ b/java/client/src/test/java/org/apache/qpid/client/SpecificMethodFrameListenerTest.java @@ -2,6 +2,8 @@ package org.apache.qpid.framing; import junit.framework.TestCase; import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; +import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9; + import org.apache.mina.common.ByteBuffer; /* @@ -58,8 +60,8 @@ public class SpecificMethodFrameListenerTest extends TestCase public void testProcessMethod() throws AMQFrameDecodingException { - ChannelCloseOkBody ccob = (ChannelCloseOkBody) ChannelCloseOkBody.getFactory().newInstance((byte) 8, (byte) 0, ByteBuffer.allocate(0), 0); - ChannelOpenOkBody coob = (ChannelOpenOkBody) ChannelOpenOkBody.getFactory().newInstance((byte) 8, (byte) 0, ByteBuffer.allocate(0), 0); + ChannelCloseOkBody ccob = MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9).createChannelCloseOkBody(); + ChannelOpenOkBody coob = ((MethodRegistry_0_9)(MethodRegistry.getMethodRegistry(ProtocolVersion.v0_9))).createChannelOpenOkBody(new byte[0]); assertTrue("This SpecificMethodFrameListener should process a ChannelCloseOkBody", close1a.processMethod(1, ccob)); assertFalse("This SpecificMethodFrameListener should NOT process a ChannelOpenOkBody", close1a.processMethod(1, coob)); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java index 575d542633..a74ae6f6d8 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java @@ -37,7 +37,7 @@ import org.apache.qpid.protocol.AMQMethodEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListener +public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListener<ChannelCloseBody> { private static final Logger _logger = LoggerFactory.getLogger(ChannelCloseMethodHandlerNoCloseOk.class); @@ -48,14 +48,15 @@ public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListe return _handler; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) + public void methodReceived(AMQStateManager stateManager, ChannelCloseBody method, int channelId) throws AMQException { _logger.debug("ChannelClose method received"); - ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); + final AMQProtocolSession session = stateManager.getProtocolSession(); - AMQConstant errorCode = AMQConstant.getConstant(method.replyCode); - AMQShortString reason = method.replyText; + + AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); + AMQShortString reason = method.getReplyText(); if (_logger.isDebugEnabled()) { _logger.debug("Channel close reply code: " + errorCode + ", reason: " + reason); @@ -95,6 +96,6 @@ public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListe } - protocolSession.channelClosed(evt.getChannelId(), errorCode, String.valueOf(reason)); + session.channelClosed(channelId, errorCode, String.valueOf(reason)); } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java index f1099ca5ab..da9d2ee9a1 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java @@ -25,20 +25,13 @@ import junit.framework.TestCase; import org.apache.qpid.AMQException; import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.handler.ClientMethodDispatcherImpl; import org.apache.qpid.client.failover.FailoverException; -import org.apache.qpid.client.failover.FailoverProtectedOperation; -import org.apache.qpid.client.failover.FailoverRetrySupport; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.protocol.AMQProtocolHandler; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.transport.TransportConnection; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelOpenBody; -import org.apache.qpid.framing.ChannelOpenOkBody; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeclareOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.jms.ConnectionListener; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.url.URLSyntaxException; @@ -55,6 +48,9 @@ import javax.jms.MessageProducer; import javax.jms.Queue; import javax.jms.Session; import javax.jms.TextMessage; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; public class ChannelCloseTest extends TestCase implements ExceptionListener, ConnectionListener { @@ -138,8 +134,11 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con /* close channel and send guff then send ok no errors + REMOVE TEST - The behaviour after server has sent close is undefined. + the server should be free to fail as it may wish to reclaim its resources + immediately after close. */ - public void testSendingMethodsAfterClose() throws Exception + /*public void testSendingMethodsAfterClose() throws Exception { try { @@ -161,6 +160,17 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con // Set StateManager to manager that ignores Close-oks AMQProtocolSession protocolSession = ((AMQConnection) _connection).getProtocolHandler().getProtocolSession(); + + MethodDispatcher d = protocolSession.getMethodDispatcher(); + + MethodDispatcher wrappedDispatcher = (MethodDispatcher) + Proxy.newProxyInstance(d.getClass().getClassLoader(), + d.getClass().getInterfaces(), + new MethodDispatcherProxyHandler( + (ClientMethodDispatcherImpl) d)); + + protocolSession.setMethodDispatcher(wrappedDispatcher); + AMQStateManager newStateManager = new NoCloseOKStateManager(protocolSession); newStateManager.changeState(oldStateManager.getCurrentState()); @@ -250,7 +260,7 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con } } } - +*/ private void createChannelAndTest(int channel) throws FailoverException { // Create A channel @@ -277,10 +287,9 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con private void sendClose(int channel) { - AMQFrame frame = - ChannelCloseOkBody.createAMQFrame(channel, - ((AMQConnection) _connection).getProtocolHandler().getProtocolMajorVersion(), - ((AMQConnection) _connection).getProtocolHandler().getProtocolMinorVersion()); + ChannelCloseOkBody body = + ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelCloseOkBody(); + AMQFrame frame = body.generateFrame(channel); ((AMQConnection) _connection).getProtocolHandler().writeFrame(frame); } @@ -338,25 +347,22 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con private void declareExchange(final int channelId, final String _type, final String _name, final boolean nowait) throws AMQException, FailoverException { -// new FailoverRetrySupport<Object, AMQException>(new FailoverProtectedOperation<Object, AMQException>() -// { -// public Object execute() throws AMQException, FailoverException -// { + ExchangeDeclareBody body = + ((AMQConnection) _connection).getProtocolHandler() + .getMethodRegistry() + .createExchangeDeclareBody(0, + new AMQShortString(_name), + new AMQShortString(_type), + true, + false, + false, + false, + nowait, + null); + AMQFrame exchangeDeclare = body.generateFrame(channelId); AMQProtocolHandler protocolHandler = ((AMQConnection) _connection).getProtocolHandler(); - AMQFrame exchangeDeclare = - ExchangeDeclareBody.createAMQFrame(channelId, - protocolHandler.getProtocolMajorVersion(), - protocolHandler.getProtocolMinorVersion(), null, // arguments - false, // autoDelete - false, // durable - new AMQShortString(_name), // exchange - false, // internal - nowait, // nowait - true, // passive - 0, // ticket - new AMQShortString(_type)); // type if (nowait) { @@ -375,9 +381,10 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con private void createChannel(int channelId) throws AMQException, FailoverException { - ((AMQConnection) _connection).getProtocolHandler().syncWrite(ChannelOpenBody.createAMQFrame(channelId, - ((AMQConnection) _connection).getProtocolHandler().getProtocolMajorVersion(), - ((AMQConnection) _connection).getProtocolHandler().getProtocolMinorVersion(), null), // outOfBand + ChannelOpenBody body = + ((AMQConnection) _connection).getProtocolHandler().getMethodRegistry().createChannelOpenBody(null); + + ((AMQConnection) _connection).getProtocolHandler().syncWrite(body.generateFrame(channelId), // outOfBand ChannelOpenOkBody.class); } @@ -409,4 +416,28 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con public void failoverComplete() { } + + private static final class MethodDispatcherProxyHandler implements InvocationHandler + { + private final ClientMethodDispatcherImpl _underlyingDispatcher; + private final ChannelCloseMethodHandlerNoCloseOk _handler = ChannelCloseMethodHandlerNoCloseOk.getInstance(); + + + public MethodDispatcherProxyHandler(ClientMethodDispatcherImpl dispatcher) + { + _underlyingDispatcher = dispatcher; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + if(method.getName().equals("dispatchChannelClose")) + { + _handler.methodReceived(_underlyingDispatcher.getStateManager(), + (ChannelCloseBody) args[0], (Integer)args[1]); + } + Method dispatcherMethod = _underlyingDispatcher.getClass().getMethod(method.getName(), method.getParameterTypes()); + return dispatcherMethod.invoke(_underlyingDispatcher, args); + + } + } } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java index d128f30727..c7eb745566 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java @@ -59,49 +59,7 @@ public class NoCloseOKStateManager extends AMQStateManager super(protocolSession); } - protected void registerListeners() - { - Map frame2handlerMap = new HashMap(); - - // we need to register a map for the null (i.e. all state) handlers otherwise you get - // a stack overflow in the handler searching code when you present it with a frame for which - // no handlers are registered - // - _state2HandlersMap.put(null, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionStartBody.class, ConnectionStartMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_STARTED, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionTuneBody.class, ConnectionTuneMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionSecureBody.class, ConnectionSecureMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_TUNED, frame2handlerMap); - - frame2handlerMap = new HashMap(); - frame2handlerMap.put(ConnectionOpenOkBody.class, ConnectionOpenOkMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_NOT_OPENED, frame2handlerMap); - - // - // ConnectionOpen handlers - // - frame2handlerMap = new HashMap(); - // Use Test Handler for Close methods to not send Close-OKs - frame2handlerMap.put(ChannelCloseBody.class, ChannelCloseMethodHandlerNoCloseOk.getInstance()); - - frame2handlerMap.put(ChannelCloseOkBody.class, ChannelCloseOkMethodHandler.getInstance()); - frame2handlerMap.put(ConnectionCloseBody.class, ConnectionCloseMethodHandler.getInstance()); - frame2handlerMap.put(BasicDeliverBody.class, BasicDeliverMethodHandler.getInstance()); - frame2handlerMap.put(BasicReturnBody.class, BasicReturnMethodHandler.getInstance()); - frame2handlerMap.put(BasicCancelOkBody.class, BasicCancelOkMethodHandler.getInstance()); - frame2handlerMap.put(ChannelFlowOkBody.class, ChannelFlowOkMethodHandler.getInstance()); - frame2handlerMap.put(QueueDeleteOkBody.class, QueueDeleteOkMethodHandler.getInstance()); - frame2handlerMap.put(ExchangeBoundOkBody.class, ExchangeBoundOkMethodHandler.getInstance()); - _state2HandlersMap.put(AMQState.CONNECTION_OPEN, frame2handlerMap); - } + } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java index c1caf8bbff..f4a8e4c1e2 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java @@ -124,7 +124,16 @@ public class ClientHandlerRegistry extends AMQStateManager { protected AMQFrame createConnectionOpenFrame(int channel, AMQShortString path, AMQShortString capabilities, boolean insist, byte major, byte minor) { - return super.createConnectionOpenFrame(channel, path, new AMQShortString(ClusterCapability.add(capabilities, _identity)), insist, major, minor); + // Be aware of possible changes to parameter order as versions change. + return ConnectionOpenBody.createAMQFrame(channel, + major, + minor, + // AMQP version (major, minor) + new AMQShortString(ClusterCapability.add(capabilities, _identity)), + // capabilities + insist, + // insist + path); } } } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleSendable.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleSendable.java index 7e5563460f..3699a9e128 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleSendable.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleSendable.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.cluster; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.MethodConverter_8_0; +import org.apache.qpid.framing.amqp_8_0.MethodConverter_8_0; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; import org.apache.qpid.server.queue.AMQMessage; diff --git a/java/common/protocol-version.xml b/java/common/protocol-version.xml index 40331a8a84..d33e78e009 100644 --- a/java/common/protocol-version.xml +++ b/java/common/protocol-version.xml @@ -27,15 +27,20 @@ <property name="generated.dir" location="${generated.path}/${generated.package}" /> <property name="generated.timestamp" location="${generated.dir}/timestamp" /> <property name="xml.spec.dir" location="${topDirectoryLocation}/../specs" /> - <property name="xml.spec.deps" value="amqp.0-8.xml cluster.0-8.xml" /> - <property name="xml.spec.list" value="${xml.spec.dir}/amqp.0-8.xml ${xml.spec.dir}/cluster.0-8.xml" /> + <property name="xml.spec.deps" value="amqp.0-8.xml amqp.0-9.xml" /> + <property name="xml.spec.list" value="${xml.spec.dir}/amqp.0-8.xml ${xml.spec.dir}/amqp.0-9.xml" /> + <property name="template.dir" value="${topDirectoryLocation}/common/templates" /> + - <target name="generate" depends="compile_generator,check_generate_deps" unless="generation.notRequired"> + <!--<target name="generate" depends="compile_generator,check_generate_deps" unless="generation.notRequired">--> + <target name="generate" depends="compile_generator" unless="generation.notRequired"> <mkdir dir="${generated.dir}"/> <java classname="org.apache.qpid.gentools.Main" fork="true" dir="${gentools.home}/src" failonerror="true"> - <arg line="-j -o ${generated.dir} -t ${gentools.home}/templ.java ${xml.spec.list}" /> + <arg line="-j -o ${generated.dir} -t ${template.dir} ${xml.spec.list}" /> <classpath> <pathelement path="${gentools.home}/src" /> + <pathelement path="${gentools.home}/lib/velocity-1.4.jar" /> + <pathelement path="${gentools.home}/lib/velocity-dep-1.4.jar" /> </classpath> </java> <touch file="${generated.timestamp}" /> @@ -44,7 +49,8 @@ <target name="check_generate_deps"> <uptodate property="generation.notRequired" targetfile="${generated.timestamp}"> <srcfiles dir="${xml.spec.dir}" includes="${xml.spec.deps}" /> - </uptodate> + <srcfiles dir="${template.dir}" includes="**/*.vm **/*.tmpl" /> + </uptodate> </target> <target name="compile_generator"> diff --git a/java/common/src/main/java/org/apache/qpid/AMQChannelException.java b/java/common/src/main/java/org/apache/qpid/AMQChannelException.java index 9efd271e4d..35f4b1f074 100644 --- a/java/common/src/main/java/org/apache/qpid/AMQChannelException.java +++ b/java/common/src/main/java/org/apache/qpid/AMQChannelException.java @@ -20,9 +20,7 @@ */ package org.apache.qpid; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ChannelCloseBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; /** @@ -63,6 +61,9 @@ public class AMQChannelException extends AMQException public AMQFrame getCloseFrame(int channel) { - return ChannelCloseBody.createAMQFrame(channel, major, minor, _classId, _methodId, getErrorCode().getCode(), new AMQShortString(getMessage())); + + MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor)); + return new AMQFrame(channel, reg.createChannelCloseBody(getErrorCode().getCode(), new AMQShortString(getMessage()),_classId,_methodId)); + } } diff --git a/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java b/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java index 7edfa648ed..fabb7f1f1f 100644 --- a/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java +++ b/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java @@ -21,9 +21,7 @@ package org.apache.qpid; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQConstant; /** @@ -66,8 +64,13 @@ public class AMQConnectionException extends AMQException public AMQFrame getCloseFrame(int channel) { - return ConnectionCloseBody.createAMQFrame(channel, major, minor, _classId, _methodId, getErrorCode().getCode(), - new AMQShortString(getMessage())); + MethodRegistry reg = MethodRegistry.getMethodRegistry(new ProtocolVersion(major,minor)); + return new AMQFrame(channel, + reg.createConnectionCloseBody(getErrorCode().getCode(), + new AMQShortString(getMessage()), + _classId, + _methodId)); + } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java b/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java index ebeea8d2b4..3abd97ddb7 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java @@ -22,18 +22,18 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public abstract class AMQBody +public interface AMQBody { - public abstract byte getFrameType(); + public byte getFrameType(); /** * Get the size of the body * @return unsigned short */ - protected abstract int getSize(); + public abstract int getSize(); - protected abstract void writePayload(ByteBuffer buffer); + public void writePayload(ByteBuffer buffer); - protected abstract void populateFromBuffer(ByteBuffer buffer, long size) - throws AMQFrameDecodingException, AMQProtocolVersionException; + //public void populateFromBuffer(ByteBuffer buffer, long size) + // throws AMQFrameDecodingException, AMQProtocolVersionException; } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java b/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java index cd5ccf8e04..e6320a07fc 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQFrameDecodingException.java @@ -38,4 +38,10 @@ public class AMQFrameDecodingException extends AMQException { super(errorCode, message, t); } + + public AMQFrameDecodingException(AMQConstant errorCode, String message) + { + super(errorCode, message); + } + } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java index f2e91083ca..4763b22290 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java @@ -23,79 +23,42 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQChannelException; import org.apache.qpid.AMQConnectionException; +import org.apache.qpid.AMQException; import org.apache.qpid.protocol.AMQConstant; -public abstract class AMQMethodBody extends AMQBody +public interface AMQMethodBody extends AMQBody { public static final byte TYPE = 1; /** AMQP version */ - protected byte major; - protected byte minor; + public byte getMajor(); - public byte getMajor() - { - return major; - } + public byte getMinor(); - public byte getMinor() - { - return minor; - } - public AMQMethodBody(byte major, byte minor) - { - this.major = major; - this.minor = minor; - } - - /** unsigned short */ - protected abstract int getBodySize(); /** @return unsigned short */ - protected abstract int getClazz(); + public int getClazz(); /** @return unsigned short */ - protected abstract int getMethod(); - - protected abstract void writeMethodPayload(ByteBuffer buffer); - - public byte getFrameType() - { - return TYPE; - } - - protected int getSize() - { - return 2 + 2 + getBodySize(); - } - - protected void writePayload(ByteBuffer buffer) - { - EncodingUtils.writeUnsignedShort(buffer, getClazz()); - EncodingUtils.writeUnsignedShort(buffer, getMethod()); - writeMethodPayload(buffer); - } - - protected abstract void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException; - - protected void populateFromBuffer(ByteBuffer buffer, long size) throws AMQFrameDecodingException - { - populateMethodBodyFromBuffer(buffer); - } - - public String toString() - { - StringBuffer buf = new StringBuffer(getClass().getName()); - buf.append("[ Class: ").append(getClazz()); - buf.append(" Method: ").append(getMethod()).append(']'); - return buf.toString(); - } + public int getMethod(); + + public void writeMethodPayload(ByteBuffer buffer); + + + public int getSize(); + + public void writePayload(ByteBuffer buffer); + + //public abstract void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException; + + //public void populateFromBuffer(ByteBuffer buffer, long size) throws AMQFrameDecodingException; + + public AMQFrame generateFrame(int channelId); + + public String toString(); + - /** - * Creates an AMQChannelException for the corresponding body type (a channel exception should include the class and - * method ids of the body it resulted from). - */ /** * Convenience Method to create a channel not found exception @@ -104,29 +67,17 @@ public abstract class AMQMethodBody extends AMQBody * * @return new AMQChannelException */ - public AMQChannelException getChannelNotFoundException(int channelId) - { - return getChannelException(AMQConstant.NOT_FOUND, "Channel not found for id:" + channelId); - } - - public AMQChannelException getChannelException(AMQConstant code, String message) - { - return new AMQChannelException(code, message, getClazz(), getMethod(), major, minor); - } - - public AMQChannelException getChannelException(AMQConstant code, String message, Throwable cause) - { - return new AMQChannelException(code, message, getClazz(), getMethod(), major, minor, cause); - } - - public AMQConnectionException getConnectionException(AMQConstant code, String message) - { - return new AMQConnectionException(code, message, getClazz(), getMethod(), major, minor); - } - - public AMQConnectionException getConnectionException(AMQConstant code, String message, Throwable cause) - { - return new AMQConnectionException(code, message, getClazz(), getMethod(), major, minor, cause); - } + public AMQChannelException getChannelNotFoundException(int channelId); + + public AMQChannelException getChannelException(AMQConstant code, String message); + + public AMQChannelException getChannelException(AMQConstant code, String message, Throwable cause); + + public AMQConnectionException getConnectionException(AMQConstant code, String message); + + + public AMQConnectionException getConnectionException(AMQConstant code, String message, Throwable cause); + + public boolean execute(MethodDispatcher methodDispatcher, int channelId) throws AMQException; } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java index cf85bdab31..1a7022c11b 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java @@ -40,7 +40,6 @@ public class AMQMethodBodyFactory implements BodyFactory public AMQBody createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException { - return _protocolSession.getRegistry().get((short) in.getUnsignedShort(), (short) in.getUnsignedShort(), in, - bodySize); + return _protocolSession.getMethodRegistry().convertToBody(in, bodySize); } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java new file mode 100644 index 0000000000..5215bcbd66 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java @@ -0,0 +1,89 @@ +package org.apache.qpid.framing;
+
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.qpid.AMQChannelException;
+import org.apache.qpid.AMQConnectionException;
+import org.apache.qpid.protocol.AMQConstant;
+
+public abstract class AMQMethodBodyImpl implements AMQMethodBody
+{
+ public static final byte TYPE = 1;
+
+ public AMQMethodBodyImpl()
+ {
+ }
+
+ public byte getFrameType()
+ {
+ return TYPE;
+ }
+
+
+ /** unsigned short */
+ abstract protected int getBodySize();
+
+
+ public AMQFrame generateFrame(int channelId)
+ {
+ return new AMQFrame(channelId, this);
+ }
+
+ /**
+ * Creates an AMQChannelException for the corresponding body type (a channel exception should include the class and
+ * method ids of the body it resulted from).
+ */
+
+ /**
+ * Convenience Method to create a channel not found exception
+ *
+ * @param channelId The channel id that is not found
+ *
+ * @return new AMQChannelException
+ */
+ public AMQChannelException getChannelNotFoundException(int channelId)
+ {
+ return getChannelException(AMQConstant.NOT_FOUND, "Channel not found for id:" + channelId);
+ }
+
+ public AMQChannelException getChannelException(AMQConstant code, String message)
+ {
+ return new AMQChannelException(code, message, getClazz(), getMethod(), getMajor(), getMinor(), null);
+ }
+
+ public AMQChannelException getChannelException(AMQConstant code, String message, Throwable cause)
+ {
+ return new AMQChannelException(code, message, getClazz(), getMethod(), getMajor(), getMinor(), cause);
+ }
+
+ public AMQConnectionException getConnectionException(AMQConstant code, String message)
+ {
+ return new AMQConnectionException(code, message, getClazz(), getMethod(), getMajor(), getMinor(), null);
+ }
+
+ public AMQConnectionException getConnectionException(AMQConstant code, String message, Throwable cause)
+ {
+ return new AMQConnectionException(code, message, getClazz(), getMethod(), getMajor(), getMinor(), cause);
+ }
+
+}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java index 359efe7eb7..0030742e94 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java @@ -26,6 +26,5 @@ import org.apache.mina.common.ByteBuffer; public abstract interface AMQMethodBodyInstanceFactory
{
- public AMQMethodBody newInstance(byte major, byte minor, ByteBuffer buffer, long size) throws AMQFrameDecodingException;
- public AMQMethodBody newInstance(byte major, byte minor, int clazzID, int methodID, ByteBuffer buffer, long size) throws AMQFrameDecodingException;
+ public AMQMethodBody newInstance(ByteBuffer buffer, long size) throws AMQFrameDecodingException;
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java b/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java index be38695384..cbee1680f7 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java @@ -22,7 +22,7 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public class ContentBody extends AMQBody +public class ContentBody implements AMQBody { public static final byte TYPE = 3; diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java index 02631a5f88..80a61544b3 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java @@ -22,7 +22,7 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public class ContentHeaderBody extends AMQBody +public class ContentHeaderBody implements AMQBody { public static final byte TYPE = 2; diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java index 712eb437db..46189b63d7 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java @@ -22,6 +22,8 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl; + public class ContentHeaderPropertiesFactory { private static final ContentHeaderPropertiesFactory _instance = new ContentHeaderPropertiesFactory(); @@ -43,7 +45,7 @@ public class ContentHeaderPropertiesFactory // AMQP version change: "Hardwired" version to major=8, minor=0 // TODO: Change so that the actual version is obtained from // the ProtocolInitiation object for this session. - if (classId == BasicConsumeBody.getClazz((byte)8, (byte)0)) + if (classId == BasicConsumeBodyImpl.CLASS_ID) { properties = new BasicContentHeaderProperties(); } diff --git a/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java b/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java index ccba8bd41e..6425f8c591 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java +++ b/java/common/src/main/java/org/apache/qpid/framing/EncodingUtils.java @@ -229,7 +229,11 @@ public class EncodingUtils encodedString[i] = (byte) cha[i]; } - writeBytes(buffer, encodedString); + // TODO: check length fits in an unsigned byte + writeUnsignedByte(buffer, (short)encodedString.length); + buffer.put(encodedString); + + } else { @@ -928,15 +932,15 @@ public class EncodingUtils public static byte[] readBytes(ByteBuffer buffer) { - short length = buffer.getUnsigned(); + long length = buffer.getUnsignedInt(); if (length == 0) { return null; } else { - byte[] dataBytes = new byte[length]; - buffer.get(dataBytes, 0, length); + byte[] dataBytes = new byte[(int)length]; + buffer.get(dataBytes, 0, (int)length); return dataBytes; } @@ -947,13 +951,14 @@ public class EncodingUtils if (data != null) { // TODO: check length fits in an unsigned byte - writeUnsignedByte(buffer, (short) data.length); + writeUnsignedInteger(buffer, (long)data.length); buffer.put(data); } else - { + { // really writing out unsigned byte - buffer.put((byte) 0); + //buffer.put((byte) 0); + writeUnsignedInteger(buffer, 0L); } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java b/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java index 7246c4a1cf..ef7163bd40 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java @@ -22,7 +22,7 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public class HeartbeatBody extends AMQBody +public class HeartbeatBody implements AMQBody { public static final byte TYPE = 8; public static AMQFrame FRAME = new HeartbeatBody().toFrame(); @@ -46,12 +46,12 @@ public class HeartbeatBody extends AMQBody return TYPE; } - protected int getSize() + public int getSize() { return 0;//heartbeats we generate have no payload } - protected void writePayload(ByteBuffer buffer) + public void writePayload(ByteBuffer buffer) { } diff --git a/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java b/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java index 8b40fe72eb..aaea771a07 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java @@ -139,7 +139,7 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData } } - public void checkVersion() throws AMQException + public ProtocolVersion checkVersion() throws AMQException { if(_protocolHeader.length != 4) @@ -180,6 +180,7 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData throw new AMQProtocolVersionException("Protocol version " + _protocolMajor + "." + _protocolMinor + " not suppoerted by this version of the Qpid broker."); } + return pv; } public String toString() diff --git a/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java b/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java index 6006e9793c..516d0c569c 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java +++ b/java/common/src/main/java/org/apache/qpid/framing/VersionSpecificRegistry.java @@ -182,7 +182,7 @@ public class VersionSpecificRegistry + " method " + methodID + ".", null);
}
- return bodyFactory.newInstance(_protocolMajorVersion, _protocolMinorVersion, classID, methodID, in, size);
+ return bodyFactory.newInstance( in, size);
}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/amqp_0_9/AMQMethodBody_0_9.java b/java/common/src/main/java/org/apache/qpid/framing/amqp_0_9/AMQMethodBody_0_9.java new file mode 100644 index 0000000000..169160a9e4 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/amqp_0_9/AMQMethodBody_0_9.java @@ -0,0 +1,188 @@ +package org.apache.qpid.framing.amqp_0_9;
+
+import org.apache.qpid.framing.EncodingUtils;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.Content;
+
+import org.apache.mina.common.ByteBuffer;
+
+public abstract class AMQMethodBody_0_9 extends org.apache.qpid.framing.AMQMethodBodyImpl
+{
+
+ public byte getMajor()
+ {
+ return 0;
+ }
+
+ public byte getMinor()
+ {
+ return 9;
+ }
+
+ public int getSize()
+ {
+ return 2 + 2 + getBodySize();
+ }
+
+ public void writePayload(ByteBuffer buffer)
+ {
+ EncodingUtils.writeUnsignedShort(buffer, getClazz());
+ EncodingUtils.writeUnsignedShort(buffer, getMethod());
+ writeMethodPayload(buffer);
+ }
+
+
+ protected byte readByte(ByteBuffer buffer)
+ {
+ return buffer.get();
+ }
+
+ protected AMQShortString readAMQShortString(ByteBuffer buffer)
+ {
+ return EncodingUtils.readAMQShortString(buffer);
+ }
+
+ protected int getSizeOf(AMQShortString string)
+ {
+ return EncodingUtils.encodedShortStringLength(string);
+ }
+
+ protected void writeByte(ByteBuffer buffer, byte b)
+ {
+ buffer.put(b);
+ }
+
+ protected void writeAMQShortString(ByteBuffer buffer, AMQShortString string)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, string);
+ }
+
+ protected int readInt(ByteBuffer buffer)
+ {
+ return buffer.getInt();
+ }
+
+ protected void writeInt(ByteBuffer buffer, int i)
+ {
+ buffer.putInt(i);
+ }
+
+ protected FieldTable readFieldTable(ByteBuffer buffer) throws AMQFrameDecodingException
+ {
+ return EncodingUtils.readFieldTable(buffer);
+ }
+
+ protected int getSizeOf(FieldTable table)
+ {
+ return EncodingUtils.encodedFieldTableLength(table); //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected void writeFieldTable(ByteBuffer buffer, FieldTable table)
+ {
+ EncodingUtils.writeFieldTableBytes(buffer, table);
+ }
+
+ protected long readLong(ByteBuffer buffer)
+ {
+ return buffer.getLong();
+ }
+
+ protected void writeLong(ByteBuffer buffer, long l)
+ {
+ buffer.putLong(l);
+ }
+
+ protected int getSizeOf(byte[] response)
+ {
+ return (response == null) ? 4 :response.length + 4;
+ }
+
+ protected void writeBytes(ByteBuffer buffer, byte[] data)
+ {
+ EncodingUtils.writeBytes(buffer,data);
+ }
+
+ protected byte[] readBytes(ByteBuffer buffer)
+ {
+ return EncodingUtils.readBytes(buffer);
+ }
+
+ protected short readShort(ByteBuffer buffer)
+ {
+ return EncodingUtils.readShort(buffer);
+ }
+
+ protected void writeShort(ByteBuffer buffer, short s)
+ {
+ EncodingUtils.writeShort(buffer, s);
+ }
+
+ protected Content readContent(ByteBuffer buffer)
+ {
+ return null; //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected int getSizeOf(Content body)
+ {
+ return 0; //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected void writeContent(ByteBuffer buffer, Content body)
+ {
+ //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected byte readBitfield(ByteBuffer buffer)
+ {
+ return readByte(buffer); //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected int readUnsignedShort(ByteBuffer buffer)
+ {
+ return buffer.getUnsignedShort(); //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected void writeBitfield(ByteBuffer buffer, byte bitfield0)
+ {
+ buffer.put(bitfield0);
+ }
+
+ protected void writeUnsignedShort(ByteBuffer buffer, int s)
+ {
+ EncodingUtils.writeUnsignedShort(buffer, s);
+ }
+
+ protected long readUnsignedInteger(ByteBuffer buffer)
+ {
+ return buffer.getUnsignedInt();
+ }
+ protected void writeUnsignedInteger(ByteBuffer buffer, long i)
+ {
+ EncodingUtils.writeUnsignedInteger(buffer, i);
+ }
+
+
+ protected short readUnsignedByte(ByteBuffer buffer)
+ {
+ return buffer.getUnsigned();
+ }
+
+ protected void writeUnsignedByte(ByteBuffer buffer, short unsignedByte)
+ {
+ EncodingUtils.writeUnsignedByte(buffer, unsignedByte);
+ }
+
+ protected long readTimestamp(ByteBuffer buffer)
+ {
+ return EncodingUtils.readTimestamp(buffer);
+ }
+
+ protected void writeTimestamp(ByteBuffer buffer, long t)
+ {
+ EncodingUtils.writeTimestamp(buffer, t);
+ }
+
+
+}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/amqp_0_9/MethodConverter_0_9.java b/java/common/src/main/java/org/apache/qpid/framing/amqp_0_9/MethodConverter_0_9.java new file mode 100644 index 0000000000..de0007c132 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/amqp_0_9/MethodConverter_0_9.java @@ -0,0 +1,126 @@ +package org.apache.qpid.framing.amqp_0_9;
+
+import org.apache.mina.common.ByteBuffer;
+
+import org.apache.qpid.framing.abstraction.AbstractMethodConverter;
+import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
+import org.apache.qpid.framing.abstraction.ContentChunk;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
+import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.amqp_0_9.*;
+import org.apache.qpid.framing.amqp_0_9.BasicPublishBodyImpl;
+
+public class MethodConverter_0_9 extends AbstractMethodConverter implements ProtocolVersionMethodConverter
+{
+ private int _basicPublishClassId;
+ private int _basicPublishMethodId;
+
+ public MethodConverter_0_9()
+ {
+ super((byte)0,(byte)9);
+
+
+ }
+
+ public AMQBody convertToBody(ContentChunk contentChunk)
+ {
+ return new ContentBody(contentChunk.getData());
+ }
+
+ public ContentChunk convertToContentChunk(AMQBody body)
+ {
+ final ContentBody contentBodyChunk = (ContentBody) body;
+
+ return new ContentChunk()
+ {
+
+ public int getSize()
+ {
+ return contentBodyChunk.getSize();
+ }
+
+ public ByteBuffer getData()
+ {
+ return contentBodyChunk.payload;
+ }
+
+ public void reduceToFit()
+ {
+ contentBodyChunk.reduceBufferToFit();
+ }
+ };
+
+ }
+
+ public void configure()
+ {
+
+ _basicPublishClassId = org.apache.qpid.framing.amqp_0_9.BasicPublishBodyImpl.CLASS_ID;
+ _basicPublishMethodId = BasicPublishBodyImpl.METHOD_ID;
+
+ }
+
+ public MessagePublishInfo convertToInfo(AMQMethodBody methodBody)
+ {
+ final BasicPublishBody publishBody = ((BasicPublishBody) methodBody);
+
+ final AMQShortString exchange = publishBody.getExchange();
+ final AMQShortString routingKey = publishBody.getRoutingKey();
+
+ return new MethodConverter_0_9.MessagePublishInfoImpl(exchange == null ? null : exchange.intern(),
+ publishBody.getImmediate(),
+ publishBody.getMandatory(),
+ routingKey == null ? null : routingKey.intern());
+
+ }
+
+ public AMQMethodBody convertToBody(MessagePublishInfo info)
+ {
+
+ return new BasicPublishBodyImpl(0,
+ info.getExchange(),
+ info.getRoutingKey(),
+ info.isMandatory(),
+ info.isImmediate()) ;
+
+ }
+
+ private static class MessagePublishInfoImpl implements MessagePublishInfo
+ {
+ private final AMQShortString _exchange;
+ private final boolean _immediate;
+ private final boolean _mandatory;
+ private final AMQShortString _routingKey;
+
+ public MessagePublishInfoImpl(final AMQShortString exchange,
+ final boolean immediate,
+ final boolean mandatory,
+ final AMQShortString routingKey)
+ {
+ _exchange = exchange;
+ _immediate = immediate;
+ _mandatory = mandatory;
+ _routingKey = routingKey;
+ }
+
+ public AMQShortString getExchange()
+ {
+ return _exchange;
+ }
+
+ public boolean isImmediate()
+ {
+ return _immediate;
+ }
+
+ public boolean isMandatory()
+ {
+ return _mandatory;
+ }
+
+ public AMQShortString getRoutingKey()
+ {
+ return _routingKey;
+ }
+ }
+}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/AMQMethodBody_8_0.java b/java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/AMQMethodBody_8_0.java new file mode 100644 index 0000000000..fd6353fa54 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/AMQMethodBody_8_0.java @@ -0,0 +1,188 @@ +package org.apache.qpid.framing.amqp_8_0;
+
+import org.apache.qpid.framing.EncodingUtils;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.Content;
+
+import org.apache.mina.common.ByteBuffer;
+
+public abstract class AMQMethodBody_8_0 extends org.apache.qpid.framing.AMQMethodBodyImpl
+{
+
+ public byte getMajor()
+ {
+ return 8;
+ }
+
+ public byte getMinor()
+ {
+ return 0;
+ }
+
+ public int getSize()
+ {
+ return 2 + 2 + getBodySize();
+ }
+
+ public void writePayload(ByteBuffer buffer)
+ {
+ EncodingUtils.writeUnsignedShort(buffer, getClazz());
+ EncodingUtils.writeUnsignedShort(buffer, getMethod());
+ writeMethodPayload(buffer);
+ }
+
+
+ protected byte readByte(ByteBuffer buffer)
+ {
+ return buffer.get();
+ }
+
+ protected AMQShortString readAMQShortString(ByteBuffer buffer)
+ {
+ return EncodingUtils.readAMQShortString(buffer);
+ }
+
+ protected int getSizeOf(AMQShortString string)
+ {
+ return EncodingUtils.encodedShortStringLength(string);
+ }
+
+ protected void writeByte(ByteBuffer buffer, byte b)
+ {
+ buffer.put(b);
+ }
+
+ protected void writeAMQShortString(ByteBuffer buffer, AMQShortString string)
+ {
+ EncodingUtils.writeShortStringBytes(buffer, string);
+ }
+
+ protected int readInt(ByteBuffer buffer)
+ {
+ return buffer.getInt();
+ }
+
+ protected void writeInt(ByteBuffer buffer, int i)
+ {
+ buffer.putInt(i);
+ }
+
+ protected FieldTable readFieldTable(ByteBuffer buffer) throws AMQFrameDecodingException
+ {
+ return EncodingUtils.readFieldTable(buffer);
+ }
+
+ protected int getSizeOf(FieldTable table)
+ {
+ return EncodingUtils.encodedFieldTableLength(table); //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected void writeFieldTable(ByteBuffer buffer, FieldTable table)
+ {
+ EncodingUtils.writeFieldTableBytes(buffer, table);
+ }
+
+ protected long readLong(ByteBuffer buffer)
+ {
+ return buffer.getLong();
+ }
+
+ protected void writeLong(ByteBuffer buffer, long l)
+ {
+ buffer.putLong(l);
+ }
+
+ protected int getSizeOf(byte[] response)
+ {
+ return (response == null) ? 4 : response.length + 4;
+ }
+
+ protected void writeBytes(ByteBuffer buffer, byte[] data)
+ {
+ EncodingUtils.writeBytes(buffer,data);
+ }
+
+ protected byte[] readBytes(ByteBuffer buffer)
+ {
+ return EncodingUtils.readBytes(buffer);
+ }
+
+ protected short readShort(ByteBuffer buffer)
+ {
+ return EncodingUtils.readShort(buffer);
+ }
+
+ protected void writeShort(ByteBuffer buffer, short s)
+ {
+ EncodingUtils.writeShort(buffer, s);
+ }
+
+ protected Content readContent(ByteBuffer buffer)
+ {
+ return null; //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected int getSizeOf(Content body)
+ {
+ return 0; //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected void writeContent(ByteBuffer buffer, Content body)
+ {
+ //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected byte readBitfield(ByteBuffer buffer)
+ {
+ return readByte(buffer); //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected int readUnsignedShort(ByteBuffer buffer)
+ {
+ return buffer.getUnsignedShort(); //To change body of created methods use File | Settings | File Templates.
+ }
+
+ protected void writeBitfield(ByteBuffer buffer, byte bitfield0)
+ {
+ buffer.put(bitfield0);
+ }
+
+ protected void writeUnsignedShort(ByteBuffer buffer, int s)
+ {
+ EncodingUtils.writeUnsignedShort(buffer, s);
+ }
+
+ protected long readUnsignedInteger(ByteBuffer buffer)
+ {
+ return buffer.getUnsignedInt();
+ }
+ protected void writeUnsignedInteger(ByteBuffer buffer, long i)
+ {
+ EncodingUtils.writeUnsignedInteger(buffer, i);
+ }
+
+
+ protected short readUnsignedByte(ByteBuffer buffer)
+ {
+ return buffer.getUnsigned();
+ }
+
+ protected void writeUnsignedByte(ByteBuffer buffer, short unsignedByte)
+ {
+ EncodingUtils.writeUnsignedByte(buffer, unsignedByte);
+ }
+
+ protected long readTimestamp(ByteBuffer buffer)
+ {
+ return EncodingUtils.readTimestamp(buffer);
+ }
+
+ protected void writeTimestamp(ByteBuffer buffer, long t)
+ {
+ EncodingUtils.writeTimestamp(buffer, t);
+ }
+
+
+}
diff --git a/java/common/src/main/java/org/apache/qpid/framing/MethodConverter_8_0.java b/java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/MethodConverter_8_0.java index 9a113f452b..7a13af8a43 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/MethodConverter_8_0.java +++ b/java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/MethodConverter_8_0.java @@ -19,12 +19,14 @@ *
*/
-package org.apache.qpid.framing;
+package org.apache.qpid.framing.amqp_8_0;
import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter;
import org.apache.qpid.framing.abstraction.ContentChunk;
import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.framing.abstraction.AbstractMethodConverter;
+import org.apache.qpid.framing.amqp_8_0.BasicPublishBodyImpl;
+import org.apache.qpid.framing.*;
import org.apache.mina.common.ByteBuffer;
@@ -73,53 +75,72 @@ public class MethodConverter_8_0 extends AbstractMethodConverter implements Prot public void configure()
{
- _basicPublishClassId = BasicPublishBody.getClazz(getProtocolMajorVersion(),getProtocolMinorVersion());
- _basicPublishMethodId = BasicPublishBody.getMethod(getProtocolMajorVersion(),getProtocolMinorVersion());
+ _basicPublishClassId = BasicPublishBodyImpl.CLASS_ID;
+ _basicPublishMethodId = BasicPublishBodyImpl.METHOD_ID;
}
public MessagePublishInfo convertToInfo(AMQMethodBody methodBody)
{
- final BasicPublishBody body = (BasicPublishBody) methodBody;
-
- return new MessagePublishInfo()
- {
+ final BasicPublishBody publishBody = ((BasicPublishBody) methodBody);
- public AMQShortString getExchange()
- {
- return body.getExchange();
- }
+ final AMQShortString exchange = publishBody.getExchange();
+ final AMQShortString routingKey = publishBody.getRoutingKey();
- public boolean isImmediate()
- {
- return body.getImmediate();
- }
-
- public boolean isMandatory()
- {
- return body.getMandatory();
- }
-
- public AMQShortString getRoutingKey()
- {
- return body.getRoutingKey();
- }
- };
+ return new MessagePublishInfoImpl(exchange == null ? null : exchange.intern(),
+ publishBody.getImmediate(),
+ publishBody.getMandatory(),
+ routingKey == null ? null : routingKey.intern());
}
public AMQMethodBody convertToBody(MessagePublishInfo info)
{
- return new BasicPublishBody(getProtocolMajorVersion(),
- getProtocolMinorVersion(),
- _basicPublishClassId,
- _basicPublishMethodId,
+ return new BasicPublishBodyImpl(0,
info.getExchange(),
- info.isImmediate(),
- info.isMandatory(),
info.getRoutingKey(),
- 0) ; // ticket
+ info.isMandatory(),
+ info.isImmediate()) ;
+
+ }
+ private static class MessagePublishInfoImpl implements MessagePublishInfo
+ {
+ private final AMQShortString _exchange;
+ private final boolean _immediate;
+ private final boolean _mandatory;
+ private final AMQShortString _routingKey;
+
+ public MessagePublishInfoImpl(final AMQShortString exchange,
+ final boolean immediate,
+ final boolean mandatory,
+ final AMQShortString routingKey)
+ {
+ _exchange = exchange;
+ _immediate = immediate;
+ _mandatory = mandatory;
+ _routingKey = routingKey;
+ }
+
+ public AMQShortString getExchange()
+ {
+ return _exchange;
+ }
+
+ public boolean isImmediate()
+ {
+ return _immediate;
+ }
+
+ public boolean isMandatory()
+ {
+ return _mandatory;
+ }
+
+ public AMQShortString getRoutingKey()
+ {
+ return _routingKey;
+ }
}
}
diff --git a/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java b/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java index 7c1d6fdaa0..035645aad2 100644 --- a/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java +++ b/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java @@ -21,6 +21,7 @@ package org.apache.qpid.protocol;
import org.apache.qpid.framing.VersionSpecificRegistry;
+import org.apache.qpid.framing.MethodRegistry;
/**
* AMQVersionAwareProtocolSession is implemented by all AMQP session classes, that need to provide an awareness to
@@ -42,5 +43,7 @@ public interface AMQVersionAwareProtocolSession extends AMQProtocolWriter, Proto *
* @return The method registry for a specific version of the AMQP.
*/
- public VersionSpecificRegistry getRegistry();
+// public VersionSpecificRegistry getRegistry();
+
+ MethodRegistry getMethodRegistry();
}
diff --git a/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java b/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java index 60a7f30185..dea80cdcf4 100644 --- a/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java +++ b/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java @@ -20,6 +20,8 @@ */
package org.apache.qpid.protocol;
+import org.apache.qpid.framing.ProtocolVersion;
+
/**
* ProtocolVersionAware is implemented by all AMQP handling classes, that need to provide an awareness to callers of
* the version of the AMQP protocol that they are able to handle.
@@ -32,6 +34,7 @@ package org.apache.qpid.protocol; public interface ProtocolVersionAware
{
/**
+ * @deprecated
* Reports the AMQP minor version, that the implementer can handle.
*
* @return The AMQP minor version.
@@ -39,9 +42,12 @@ public interface ProtocolVersionAware public byte getProtocolMinorVersion();
/**
+ * @deprecated
* Reports the AMQP major version, that the implementer can handle.
*
* @return The AMQP major version.
*/
public byte getProtocolMajorVersion();
+
+ public ProtocolVersion getProtocolVersion();
}
diff --git a/java/common/templates/method/MethodBodyInterface.vm b/java/common/templates/method/MethodBodyInterface.vm new file mode 100644 index 0000000000..d5feba12de --- /dev/null +++ b/java/common/templates/method/MethodBodyInterface.vm @@ -0,0 +1,62 @@ +#macro( UpperCamel $name ) +#set( $name = "${name.substring(0,1).toUpperCase()}${name.substring(1)}" ) +#end +#macro( toUpperCamel $name )${name.substring(0,1).toUpperCase()}${name.substring(1)}#end + + + +#set( $amqp_ClassName = $amqpClass.Name) +#UpperCamel( $amqp_ClassName ) +#set( $amqp_MethodName = $amqpMethod.Name ) +#UpperCamel( $amqp_MethodName ) +#set( $javaClassName = "${amqp_ClassName}${amqp_MethodName}Body" ) + + +#set( $filename = "${javaClassName}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${generator} - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + + +package org.apache.qpid.framing; + + +public interface ${javaClassName} extends EncodableAMQDataBlock, AMQMethodBody +{ + + +#foreach( $field in $amqpMethod.Fields ) + +#if( $amqpMethod.isCommon( $field ) ) + public $field.ConsistentNativeType get#toUpperCamel( ${field.Name} )(); +#end +#end + + + +} diff --git a/java/common/templates/method/version/MethodBodyClass.vm b/java/common/templates/method/version/MethodBodyClass.vm new file mode 100644 index 0000000000..9b2ba0fa39 --- /dev/null +++ b/java/common/templates/method/version/MethodBodyClass.vm @@ -0,0 +1,209 @@ +#macro( UpperCamel $name ) +#set( $name = "${name.substring(0,1).toUpperCase()}${name.substring(1)}" ) +#end +#macro( toUpperCamel $name )${name.substring(0,1).toUpperCase()}${name.substring(1)}#end + + + +#set( $amqp_ClassName = $amqpClass.Name) +#UpperCamel( $amqp_ClassName ) +#set( $amqp_MethodName = $amqpMethod.Name ) +#UpperCamel( $amqp_MethodName ) +#set( $javaClassName = "${amqp_ClassName}${amqp_MethodName}BodyImpl" ) +#set( $interfaceName = "${amqp_ClassName}${amqp_MethodName}Body" ) +#set( $amqpPackageName = "amqp_$version.getMajor()_$version.getMinor()" ) + +#set( $filename = "${amqpPackageName}/${javaClassName}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${generator} - do not modify. + * Supported AMQP version: + * $version.getMajor()-$version.getMinor() + */ + +#set( $clazz = $amqpClass.asSingleVersionClass( $version ) ) +#set( $method = $amqpMethod.asSingleVersionMethod( $version ) ) + +package org.apache.qpid.framing.amqp_$version.getMajor()_$version.getMinor(); + +import java.util.HashMap; + +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.framing.*; +import org.apache.qpid.AMQException; + +public class ${javaClassName} extends AMQMethodBody_$version.getMajor()_$version.getMinor() implements $interfaceName +{ + private static final AMQMethodBodyInstanceFactory FACTORY_INSTANCE = new AMQMethodBodyInstanceFactory() + { + public AMQMethodBody newInstance(ByteBuffer in, long size) throws AMQFrameDecodingException + { + return new ${javaClassName}(in); + } + + + }; + + + public static AMQMethodBodyInstanceFactory getFactory() + { + return FACTORY_INSTANCE; + } + + public static int CLASS_ID = $clazz.ClassId; + + public static int METHOD_ID = $method.MethodId; + + + + // Fields declared in specification +#foreach( $field in $method.ConsolidatedFields ) + private final $field.NativeType _$field.getName(); // $field.UnderlyingFields +#end + + + // Constructor + + public ${javaClassName}(ByteBuffer buffer) throws AMQFrameDecodingException + { +#foreach( $field in $method.ConsolidatedFields ) + _$field.Name = read$field.getEncodingType()( buffer ); +#end + } + + public ${javaClassName}( +#foreach( $field in $method.FieldList ) +#if( $velocityCount == $method.getFieldList().size() ) + $field.NativeType $field.Name +#else + $field.NativeType $field.Name, +#end +#end + ) + { +#set( $consolidatedFieldName = "" ) +#foreach( $field in $method.FieldList ) +#if( $method.isConsolidated( $field.Name ) ) +#if( !$method.getConsolidatedFieldName( $field.Name ).equals( $consolidatedFieldName ) ) +#if( !$consolidatedFieldName.equals("") ) + _$consolidatedFieldName = $consolidatedFieldName; // 1 +#end +#set( $consolidatedFieldName = $method.getConsolidatedFieldName( $field.Name ) ) + byte $consolidatedFieldName = (byte)0; +#end + if( $field.Name ) + { + $consolidatedFieldName = (byte) (((int) $consolidatedFieldName) | (1 << $method.getPositionInBitField( $field.Name ))); + } +#if( $velocityCount == $method.getFieldList().size()) + _$consolidatedFieldName = $consolidatedFieldName; +#else + +#end +#else +#if( !$consolidatedFieldName.equals("") ) + _$consolidatedFieldName = $consolidatedFieldName; +#end +#set( $consolidatedFieldName = "" ) + _$field.Name = $field.Name; +#end +#end + } + + public int getClazz() + { + return CLASS_ID; + } + + public int getMethod() + { + return METHOD_ID; + } + + +#foreach( $field in $method.FieldList ) + public final $field.NativeType get#toUpperCamel( ${field.Name} )() + { +#if( $method.isConsolidated( $field.Name ) ) + return (((int)(_$method.getConsolidatedFieldName( $field.Name ))) & ( 1 << $method.getPositionInBitField( $field.Name ))) != 0; +#else + return _$field.Name; +#end + } +#end + + protected int getBodySize() + { +#set( $fixedSize = 0 ) +#foreach( $field in $method.ConsolidatedFields ) +#if( $field.isFixedSize() ) +#set( $fixedSize = $fixedSize + $field.Size ) +#end +#end + int size = $fixedSize; +#foreach( $field in $method.ConsolidatedFields ) +#if( ! $field.isFixedSize() ) + size += getSizeOf( _$field.Name ); +#end +#end + return size; + } + + public void writeMethodPayload(ByteBuffer buffer) + { +#foreach( $field in $method.ConsolidatedFields ) + write$field.getEncodingType()( buffer, _$field.Name ); +#end + } + + public boolean execute(MethodDispatcher dispatcher, int channelId) throws AMQException + { +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) +#if( $amqpMethod.inAllVersions() ) + return dispatcher.dispatch${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}(this, channelId); +#else + return ((MethodDispatcher_$version.getMajor()_$version.getMinor())dispatcher).dispatch${amqp_ClassName}${amqpMethodNameUpperCamel}(this, channelId); + +#end + + } + + + public String toString() + { + StringBuilder buf = new StringBuilder("[$javaClassName: "); +#foreach( $field in $method.FieldList ) + buf.append( "$field.Name=" ); + buf.append( get#toUpperCamel( $field.Name )() ); +#if( $velocityCount != $method.FieldList.size() ) + buf.append( ", " ); +#end +#end + buf.append("]"); + return buf.toString(); + } + + +} diff --git a/java/common/templates/model/ClientMethodDispatcherInterface.vm b/java/common/templates/model/ClientMethodDispatcherInterface.vm new file mode 100644 index 0000000000..9e4aee7dee --- /dev/null +++ b/java/common/templates/model/ClientMethodDispatcherInterface.vm @@ -0,0 +1,56 @@ +#set( $filename = "ClientMethodDispatcher.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + +package org.apache.qpid.framing; + +import org.apache.qpid.AMQException; + + +public interface ClientMethodDispatcher +{ + +#foreach( $amqpClass in $model.getClasses() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) +#foreach( $amqpMethodVersions in $amqpClass.getMethods() ) +#if( $amqpMethodVersions.inAllVersions() ) +#set( $amqpMethod = $amqpMethodVersions.asSingleVersionMethod($amqpMethodVersions.getVersionSet().first()) ) +#if( $amqpMethod.isClientMethod() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + public boolean dispatch${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}(${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body body, int channelId) throws AMQException; +#end +#end +#end +#end + +}
\ No newline at end of file diff --git a/java/common/templates/model/MethodDispatcherInterface.vm b/java/common/templates/model/MethodDispatcherInterface.vm new file mode 100644 index 0000000000..ff14715fef --- /dev/null +++ b/java/common/templates/model/MethodDispatcherInterface.vm @@ -0,0 +1,39 @@ +#set( $filename = "MethodDispatcher.java")
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/*
+ * This file is auto-generated by $generator - do not modify.
+ * Supported AMQP version:
+ #foreach( $supportedVersion in $model.VersionSet )
+ * $supportedVersion.getMajor()-$supportedVersion.getMinor()
+ #end
+ */
+
+package org.apache.qpid.framing;
+
+import org.apache.qpid.AMQException;
+
+
+public interface MethodDispatcher extends
+ ClientMethodDispatcher, ServerMethodDispatcher
+{
+}
\ No newline at end of file diff --git a/java/common/templates/model/MethodRegistryClass.vm b/java/common/templates/model/MethodRegistryClass.vm new file mode 100644 index 0000000000..759e5e4a42 --- /dev/null +++ b/java/common/templates/model/MethodRegistryClass.vm @@ -0,0 +1,104 @@ +#set( $filename = "MethodRegistry.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + +package org.apache.qpid.framing; + +import org.apache.mina.common.ByteBuffer; + +import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; + +import java.util.Map; +import java.util.HashMap; + + +public abstract class MethodRegistry +{ + private static final Map<ProtocolVersion, MethodRegistry> _registries = + new HashMap<ProtocolVersion, MethodRegistry>(); + +#foreach( $supportedVersion in $model.VersionSet ) + +#set( $verName = "_$supportedVersion.getMajor()_$supportedVersion.getMinor()" ) +#set( $regPackage = "org.apache.qpid.framing.amqp$verName" ) + public static final MethodRegistry registry_$supportedVersion.getMajor()_$supportedVersion.getMinor() = + new ${regPackage}.MethodRegistry${verName}(); + +#end + + + public abstract AMQMethodBody convertToBody(ByteBuffer in, long size) + throws AMQFrameDecodingException; + + public abstract int getMaxClassId(); + + public abstract int getMaxMethodId(int classId); + + + protected MethodRegistry(ProtocolVersion pv) + { + _registries.put(pv, this); + } + + public static MethodRegistry getMethodRegistry(ProtocolVersion pv) + { + return _registries.get(pv); + } + +#foreach( $amqpClass in $model.getClasses() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) + +#foreach( $amqpMethodVersions in $amqpClass.getMethods() ) +#if( $amqpMethodVersions.isVersionInterfaceConsistent() ) +#set( $amqpMethod = $amqpMethodVersions.asSingleVersionMethod($amqpMethodVersions.getVersionSet().first()) ) + +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + public abstract ${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body create${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body( +#foreach( $field in $amqpMethod.FieldList ) +#if( $velocityCount == $amqpMethod.getFieldList().size() ) + final $field.NativeType $field.Name +#else + final $field.NativeType $field.Name, +#end +#end + ); + + +#end +#end +#end + + + public abstract ProtocolVersionMethodConverter getProtocolVersionMethodConverter(); + +}
\ No newline at end of file diff --git a/java/common/templates/model/ProtocolVersionListClass.vm b/java/common/templates/model/ProtocolVersionListClass.vm new file mode 100644 index 0000000000..d56d14e1ed --- /dev/null +++ b/java/common/templates/model/ProtocolVersionListClass.vm @@ -0,0 +1,155 @@ +#set( $filename = "ProtocolVersion.java" ) +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +/* +* This file is auto-generated by $generator - do not modify. +* Supported AMQP versions: +#foreach( $version in $model.getVersionSet() ) +* $version.getMajor()-$version.getMinor() +#end +*/ + +package org.apache.qpid.framing; + +import java.util.SortedSet; +import java.util.Collections; +import java.util.TreeSet; + + +public class ProtocolVersion implements Comparable +{ + private final byte _majorVersion; + private final byte _minorVersion; + + + public ProtocolVersion(byte majorVersion, byte minorVersion) + { + _majorVersion = majorVersion; + _minorVersion = minorVersion; + } + + public byte getMajorVersion() + { + return _majorVersion; + } + + public byte getMinorVersion() + { + return _minorVersion; + } + + + public int compareTo(Object o) + { + ProtocolVersion pv = (ProtocolVersion) o; + + /* + * 0-8 has it's major and minor numbers the wrong way round (it's actually 8-0)... + * so we need to deal with that case specially + */ + + if((_majorVersion == (byte) 8) && (_minorVersion == (byte) 0)) + { + ProtocolVersion fixedThis = new ProtocolVersion(_minorVersion, _majorVersion); + return fixedThis.compareTo(pv); + } + + if((pv.getMajorVersion() == (byte) 8) && (pv.getMinorVersion() == (byte) 0)) + { + ProtocolVersion fixedOther = new ProtocolVersion(pv.getMinorVersion(), pv.getMajorVersion()); + return this.compareTo(fixedOther); + } + + if(_majorVersion > pv.getMajorVersion()) + { + return 1; + } + else if(_majorVersion < pv.getMajorVersion()) + { + return -1; + } + else if(_minorVersion > pv.getMinorVersion()) + { + return 1; + } + else if(getMinorVersion() < pv.getMinorVersion()) + { + return -1; + } + else + { + return 0; + } + + } + + public boolean equals(Object o) + { + return o != null && (o == this || (compareTo(o) == 0)); + } + + public int hashCode() + { + return (0xFF & (int)_minorVersion) | ((0xFF & (int)_majorVersion) << 8); + } + + + public boolean isSupported() + { + return _supportedVersions.contains(this); + } + + public static ProtocolVersion getLatestSupportedVersion() + { + return _supportedVersions.last(); + } + + private static final SortedSet<ProtocolVersion> _supportedVersions; + + +#foreach( $version in $model.getVersionSet() ) +#set( $versionId = "v$version.getMajor()_$version.getMinor()" ) + public static final ProtocolVersion $versionId = new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor()); +#end + + static + { + SortedSet<ProtocolVersion> versions = new TreeSet<ProtocolVersion>(); + +#foreach( $version in $model.getVersionSet() ) +#set( $versionId = "v$version.getMajor()_$version.getMinor()" ) + versions.add($versionId); +#end + _supportedVersions = Collections.unmodifiableSortedSet(versions); + } + + + public static SortedSet<ProtocolVersion> getSupportedProtocolVersions() + { + return _supportedVersions; + } + + + + + +} diff --git a/java/common/templates/model/ServerMethodDispatcherInterface.vm b/java/common/templates/model/ServerMethodDispatcherInterface.vm new file mode 100644 index 0000000000..b80d6027b7 --- /dev/null +++ b/java/common/templates/model/ServerMethodDispatcherInterface.vm @@ -0,0 +1,56 @@ +#set( $filename = "ServerMethodDispatcher.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + +package org.apache.qpid.framing; + +import org.apache.qpid.AMQException; + + +public interface ServerMethodDispatcher +{ + +#foreach( $amqpClass in $model.getClasses() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) +#foreach( $amqpMethodVersions in $amqpClass.getMethods() ) +#if( $amqpMethodVersions.inAllVersions() ) +#set( $amqpMethod = $amqpMethodVersions.asSingleVersionMethod($amqpMethodVersions.getVersionSet().first()) ) +#if( $amqpMethod.isServerMethod() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + public boolean dispatch${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}(${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body body, int channelId) throws AMQException; +#end +#end +#end +#end + +}
\ No newline at end of file diff --git a/java/common/templates/model/version/AmqpConstantsClass.vm b/java/common/templates/model/version/AmqpConstantsClass.vm new file mode 100644 index 0000000000..8d459f2977 --- /dev/null +++ b/java/common/templates/model/version/AmqpConstantsClass.vm @@ -0,0 +1,37 @@ +&{AmqpConstants.java} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +package org.apache.qpid.framing; + +class AmqpConstants +{ + // Constant getValue methods + +%{TLIST} ${const_get_method} + +} diff --git a/java/common/templates/model/version/ClientMethodDispatcherInterface.vm b/java/common/templates/model/version/ClientMethodDispatcherInterface.vm new file mode 100644 index 0000000000..80705c1a39 --- /dev/null +++ b/java/common/templates/model/version/ClientMethodDispatcherInterface.vm @@ -0,0 +1,55 @@ +#set( $filename = "amqp_$version.getMajor()_$version.getMinor()/ClientMethodDispatcher_${version.getMajor()}_${version.getMinor()}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + +package org.apache.qpid.framing.amqp_$version.getMajor()_$version.getMinor(); + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.*; + + +public interface ClientMethodDispatcher_${version.getMajor()}_${version.getMinor()} extends ClientMethodDispatcher +{ + +#foreach( $amqpClass in $model.getClasses() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) +#foreach( $amqpMethodVersions in $amqpClass.getMethods() ) +#set( $amqpMethod = $amqpMethodVersions.asSingleVersionMethod($amqpMethodVersions.getVersionSet().first()) ) +#if( $amqpMethod.isClientMethod() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + public boolean dispatch${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}(${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body body, int channelId) throws AMQException; +#end +#end +#end + +}
\ No newline at end of file diff --git a/java/common/templates/model/version/MethodDispatcherInterface.vm b/java/common/templates/model/version/MethodDispatcherInterface.vm new file mode 100644 index 0000000000..8a7b667a91 --- /dev/null +++ b/java/common/templates/model/version/MethodDispatcherInterface.vm @@ -0,0 +1,43 @@ +#set( $filename = "amqp_$version.getMajor()_$version.getMinor()/MethodDispatcher_${version.getMajor()}_${version.getMinor()}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + +package org.apache.qpid.framing.amqp_$version.getMajor()_$version.getMinor(); + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.*; + + +public interface MethodDispatcher_${version.getMajor()}_${version.getMinor()} + extends MethodDispatcher, + ServerMethodDispatcher_${version.getMajor()}_${version.getMinor()}, + ClientMethodDispatcher_${version.getMajor()}_${version.getMinor()} +{ + +}
\ No newline at end of file diff --git a/java/common/templates/model/version/MethodRegistryClass.vm b/java/common/templates/model/version/MethodRegistryClass.vm new file mode 100644 index 0000000000..277605e34b --- /dev/null +++ b/java/common/templates/model/version/MethodRegistryClass.vm @@ -0,0 +1,193 @@ +#set( $filename = "amqp_$version.getMajor()_$version.getMinor()/MethodRegistry_${version.getMajor()}_${version.getMinor()}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + * $version.getMajor()-$version.getMinor() + */ + +package org.apache.qpid.framing.amqp_${version.getMajor()}_${version.getMinor()}; + +import org.apache.qpid.framing.*; +import org.apache.qpid.protocol.AMQConstant; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.mina.common.ByteBuffer; + +import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; + + +public class MethodRegistry_$version.getMajor()_$version.getMinor() extends MethodRegistry +{ + + private static final Logger _log = LoggerFactory.getLogger(MethodRegistry.class); + + private ProtocolVersionMethodConverter _protocolVersionConverter = new MethodConverter_$version.getMajor()_$version.getMinor()(); + +#set( $specificModel = $model.asSingleVersionModel() ) + + +#set( $maxClassId = $specificModel.getMaximumClassId()+1 ) + private final AMQMethodBodyInstanceFactory[][] _factories = new AMQMethodBodyInstanceFactory[$maxClassId][]; + + public MethodRegistry_$version.getMajor()_$version.getMinor()() + { + this(new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor())); + } + + public MethodRegistry_$version.getMajor()_$version.getMinor()(ProtocolVersion pv) + { + super(pv); +#foreach( $amqpClass in $specificModel.getClassList() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) + + + + // Register method body instance factories for the $amqpClassNameUpperCamel class. + +#set( $maxMethodId = $amqpClass.getMaximumMethodId()+1 ) + _factories[$amqpClass.getClassId()] = new AMQMethodBodyInstanceFactory[$maxMethodId]; + +#foreach( $amqpMethod in $amqpClass.getMethodList() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + _factories[$amqpClass.getClassId()][$amqpMethod.getMethodId()] = ${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}BodyImpl.getFactory(); +#end + +#end + + + } + + + public AMQMethodBody convertToBody(ByteBuffer in, long size) + throws AMQFrameDecodingException + { + int classId = in.getUnsignedShort(); + int methodId = in.getUnsignedShort(); + + AMQMethodBodyInstanceFactory bodyFactory; + try + { + bodyFactory = _factories[classId][methodId]; + } + catch(NullPointerException e) + { + throw new AMQFrameDecodingException(AMQConstant.COMMAND_INVALID, + "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + } + catch(IndexOutOfBoundsException e) + { + if(classId >= _factories.length) + { + throw new AMQFrameDecodingException(AMQConstant.COMMAND_INVALID, + "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + + } + else + { + throw new AMQFrameDecodingException(AMQConstant.COMMAND_INVALID, + "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + + } + } + + + if (bodyFactory == null) + { + throw new AMQFrameDecodingException(AMQConstant.COMMAND_INVALID, + "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + } + + + return bodyFactory.newInstance(in, size); + + + } + + + public int getMaxClassId() + { + return $specificModel.getMaximumClassId(); + } + + public int getMaxMethodId(int classId) + { + return _factories[classId].length - 1; + } + + + +#foreach( $amqpClass in $specificModel.getClassList() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) + + +#foreach( $amqpMethod in $amqpClass.getMethodList() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + public ${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body create${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body( +#foreach( $field in $amqpMethod.FieldList ) +#if( $velocityCount == $amqpMethod.getFieldList().size() ) + final $field.NativeType $field.Name +#else + final $field.NativeType $field.Name, +#end +#end + ) + { + return new ${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}BodyImpl( +#foreach( $field in $amqpMethod.FieldList ) +#if( $velocityCount == $amqpMethod.getFieldList().size() ) + $field.Name +#else + $field.Name, +#end +#end + ); + } + +#end + +#end + + + public ProtocolVersionMethodConverter getProtocolVersionMethodConverter() + { + return _protocolVersionConverter; + } + + +} diff --git a/java/common/templates/model/version/ServerMethodDispatcherInterface.vm b/java/common/templates/model/version/ServerMethodDispatcherInterface.vm new file mode 100644 index 0000000000..db388fcc65 --- /dev/null +++ b/java/common/templates/model/version/ServerMethodDispatcherInterface.vm @@ -0,0 +1,55 @@ +#set( $filename = "amqp_$version.getMajor()_$version.getMinor()/ServerMethodDispatcher_${version.getMajor()}_${version.getMinor()}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + #foreach( $supportedVersion in $model.VersionSet ) + * $supportedVersion.getMajor()-$supportedVersion.getMinor() + #end + */ + +package org.apache.qpid.framing.amqp_$version.getMajor()_$version.getMinor(); + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.*; + + +public interface ServerMethodDispatcher_${version.getMajor()}_${version.getMinor()} extends ServerMethodDispatcher +{ + +#foreach( $amqpClass in $model.getClasses() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) +#foreach( $amqpMethodVersions in $amqpClass.getMethods() ) +#set( $amqpMethod = $amqpMethodVersions.asSingleVersionMethod($amqpMethodVersions.getVersionSet().first()) ) +#if( $amqpMethod.isServerMethod() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + public boolean dispatch${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}(${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}Body body, int channelId) throws AMQException; +#end +#end +#end + +}
\ No newline at end of file diff --git a/java/pom.xml b/java/pom.xml index 5efec51a60..1abe0c6836 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -150,7 +150,6 @@ under the License. <module>common</module> <module>broker</module> <module>client</module> - <module>cluster</module> <module>systests</module> <module>perftests</module> <module>integrationtests</module> @@ -587,11 +586,6 @@ under the License. <artifactId>qpid-mgmt-client</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.apache.qpid</groupId> - <artifactId>qpid-cluster</artifactId> - <version>${project.version}</version> - </dependency> </dependencies> </dependencyManagement> diff --git a/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java b/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java index 0ad6502755..fcee3c7de4 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java +++ b/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java @@ -21,10 +21,7 @@ package org.apache.qpid.server.queue; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.VersionSpecificRegistry; +import org.apache.qpid.framing.*; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.output.ProtocolOutputConverterRegistry; @@ -188,16 +185,33 @@ public class MockProtocolSession implements AMQProtocolSession return null; //To change body of implemented methods use File | Settings | File Templates. } + public MethodRegistry getMethodRegistry() + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public MethodDispatcher getMethodDispatcher() + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + public byte getProtocolMajorVersion() { - return 8; //To change body of implemented methods use File | Settings | File Templates. + return getProtocolVersion().getMajorVersion(); } public byte getProtocolMinorVersion() { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return getProtocolVersion().getMinorVersion(); + } + + + public ProtocolVersion getProtocolVersion() + { + return ProtocolVersion.getLatestSupportedVersion(); //To change body of implemented methods use File | Settings | File Templates. } + public VersionSpecificRegistry getRegistry() { return null; //To change body of implemented methods use File | Settings | File Templates. diff --git a/specs/amqp.0-8.xml b/specs/amqp.0-8.xml index bfb9ee4658..0463f45fa9 100644 --- a/specs/amqp.0-8.xml +++ b/specs/amqp.0-8.xml @@ -790,7 +790,7 @@ localised reply text class of the method. </doc> </field> - <field name="method id" domain="class id"> + <field name="method id" domain="method id"> failing method ID <doc> When the close is provoked by a method exception, this is the @@ -1354,6 +1354,7 @@ localised reply text </method> <method name="bound" synchronous="1" index="22"> + <chassis name="server" implement="SHOULD"/> <field name="exchange" domain="exchange name"/> <field name = "routing key" type = "shortstr"> Message routing key @@ -1368,6 +1369,7 @@ localised reply text <method name="bound-ok" synchronous="1" index="23"> <field name="reply code" domain="reply code"/> <field name="reply text" domain="reply text"/> + <chassis name="client" implement="SHOULD"/> </method> </class> diff --git a/specs/amqp.0-9.xml b/specs/amqp.0-9.xml index 9d1b488c03..1615fea99d 100644 --- a/specs/amqp.0-9.xml +++ b/specs/amqp.0-9.xml @@ -1659,6 +1659,29 @@ <doc>This method confirms the deletion of an exchange.</doc> <chassis name = "client" implement = "MUST" /> </method> + + <!-- RG : Added Exchange.bound and Exchange.bound-ok --> + <method name="bound" synchronous="1" index="22"> + <chassis name="server" implement="SHOULD"/> + <field name="exchange" domain="exchange-name"/> + <field name = "routing-key" type = "shortstr"> + Message routing key + <doc> + Specifies the routing key for the message. The routing key is + used for routing messages depending on the exchange configuration. + </doc> + </field> + <field name = "queue" domain = "queue name"/> + </method> + + <method name="bound-ok" synchronous="1" index="23"> + <field name="reply-code" domain="reply-code"/> + <field name="reply-text" domain="reply-text"/> + <chassis name="client" implement="SHOULD"/> + </method> + + + </class> <!-- == QUEUE ============================================================ --> @@ -2704,7 +2727,9 @@ </doc> </field> - <field name = "filter" domain = "table" label = "arguments for consuming"> + <!-- RG changed name from filter to arguments on basic.consume: this is inline with qpid0-8 and 0-10 and has no effect on the wire level encoding + <field name = "arguments" domain = "table" label = "arguments for consuming"> --> + <field name = "arguments" domain = "table" label = "arguments for consuming"> <doc> A set of filters for the consume. The syntax and semantics of these filters depends on the providers implementation. @@ -3183,6 +3208,45 @@ </doc> </field> </method> + + + <!-- RG : Added recover-sync and recover-sync-ok to give a synchronous recover without interfering with the correct 0-9 recover method --> + <method name = "recover-sync" index = "102"> + redeliver unacknowledged messages + <doc> + This method asks the broker to redeliver all unacknowledged messages on a + specified channel. Zero or more messages may be redelivered. This method + is only allowed on non-transacted channels. + </doc> + <chassis name = "server" implement = "MUST" /> + + <field name = "requeue" type = "bit"> + requeue the message + <doc> + If this field is zero, the message will be redelivered to the original + recipient. If this bit is 1, the server will attempt to requeue the + message, potentially then delivering it to an alternative subscriber. + </doc> + </field> + <doc name="rule"> + The server MUST set the redelivered flag on all messages that are resent. + </doc> + <doc name="rule"> + The server MUST raise a channel exception if this is called on a + transacted channel. + </doc> + <response name="recover-sync-ok"/> + </method> + <method name="recover-sync-ok" synchronous="1" index="101"> + confirm a successful recover + <doc> + This method confirms to the client that the recover succeeded. + Note that if an recover fails, the server raises a channel exception. + </doc> + <chassis name="client" implement="MUST"/> + </method> + + </class> <!-- == FILE ============================================================= --> |