summaryrefslogtreecommitdiff
path: root/gentools
diff options
context:
space:
mode:
Diffstat (limited to 'gentools')
-rw-r--r--gentools/LICENSE202
-rw-r--r--gentools/NOTICE2
-rw-r--r--gentools/README.txt61
-rwxr-xr-xgentools/build37
-rw-r--r--gentools/build.xml43
-rw-r--r--gentools/lib/LICENSE0
-rw-r--r--gentools/lib/NOTICE0
-rw-r--r--gentools/lib/README.txt0
-rw-r--r--gentools/lib/velocity-1.4.jarbin361173 -> 0 bytes
-rw-r--r--gentools/lib/velocity-dep-1.4.jarbin517761 -> 0 bytes
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpClass.java197
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpClassMap.java29
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpConstant.java191
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java152
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpDomain.java89
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java128
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java62
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpField.java269
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java452
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java77
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpMethod.java351
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java36
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpModel.java132
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java96
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java76
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java29
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpParseException.java30
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java30
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java30
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpVersion.java72
-rw-r--r--gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java79
-rw-r--r--gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java29
-rw-r--r--gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java26
-rw-r--r--gentools/src/org/apache/qpid/gentools/ConsolidatedField.java120
-rw-r--r--gentools/src/org/apache/qpid/gentools/CppGenerator.java1716
-rw-r--r--gentools/src/org/apache/qpid/gentools/DotnetGenerator.java382
-rw-r--r--gentools/src/org/apache/qpid/gentools/GenerateMethod.java27
-rw-r--r--gentools/src/org/apache/qpid/gentools/Generator.java857
-rw-r--r--gentools/src/org/apache/qpid/gentools/JavaGenerator.java1826
-rw-r--r--gentools/src/org/apache/qpid/gentools/LanguageConverter.java42
-rw-r--r--gentools/src/org/apache/qpid/gentools/Main.java301
-rw-r--r--gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java26
-rw-r--r--gentools/src/org/apache/qpid/gentools/NodeAware.java47
-rw-r--r--gentools/src/org/apache/qpid/gentools/Printable.java28
-rw-r--r--gentools/src/org/apache/qpid/gentools/SingleVersionClass.java103
-rw-r--r--gentools/src/org/apache/qpid/gentools/SingleVersionField.java68
-rw-r--r--gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java154
-rw-r--r--gentools/src/org/apache/qpid/gentools/SingleVersionModel.java71
-rw-r--r--gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java30
-rw-r--r--gentools/src/org/apache/qpid/gentools/Utils.java159
-rw-r--r--gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java26
-rw-r--r--gentools/templ.cpp/method/MethodBodyClass.h.tmpl112
-rw-r--r--gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl82
-rw-r--r--gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl52
-rw-r--r--gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl75
-rw-r--r--gentools/templ.cpp/model/AMQP_Constants.h.tmpl34
-rw-r--r--gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl42
-rw-r--r--gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl62
-rw-r--r--gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl57
-rw-r--r--gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl83
-rw-r--r--gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl51
-rw-r--r--gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl74
-rw-r--r--gentools/templ.java/PropertyContentHeaderClass.tmpl208
-rw-r--r--gentools/templ.java/method/version/MethodBodyClass.vm190
-rw-r--r--gentools/templ.java/model/ProtocolVersionListClass.vm154
-rw-r--r--gentools/templ.java/model/version/AmqpConstantsClass.vm37
-rw-r--r--gentools/templ.java/model/version/MethodRegistryClass.vm145
-rw-r--r--gentools/xml-src/amqp-0.10.test.xml4241
-rw-r--r--gentools/xml-src/amqp-0.8.test.xml3959
-rw-r--r--gentools/xml-src/amqp-0.9.test.xml4282
-rw-r--r--gentools/xml-src/cluster-0.9.test.xml59
71 files changed, 0 insertions, 22989 deletions
diff --git a/gentools/LICENSE b/gentools/LICENSE
deleted file mode 100644
index 43fa6abd19..0000000000
--- a/gentools/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
- 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/NOTICE b/gentools/NOTICE
deleted file mode 100644
index 09e9ae4902..0000000000
--- a/gentools/NOTICE
+++ /dev/null
@@ -1,2 +0,0 @@
-This product includes software developed by The Apache Software Foundation (http://www.apache.org/).
-
diff --git a/gentools/README.txt b/gentools/README.txt
deleted file mode 100644
index 94f705b064..0000000000
--- a/gentools/README.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-================================================================================
-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.
-================================================================================
-
-AMQP MULTI_VERSION CODE GENERATOR
-
-This directory contains the first part of the new multi-AMQP-version code
-generator. The Java generation is almost complete, C++ will follow.
-
-NOTE: The generator has NOT been integrated into the current build, and is
-included here to run stand-alone for the purposes of review and comment. As
-currently configured, this generator will not interact with any file or
-directory outside of this directory.
-
-To build (from this directory):
-rm org/apache/qpid/gentools/*.class
-javac org/apache/qpid/gentools/Main.java
-
-Make sure you are using Sun's JDK1.5.0; Eclipse and gcj do not work.
-
-To run (from this directory):
-java org/apache/qpid/gentools/Main -j [xml_spec_file, ...]
-
-XML test files are located in the xml-src directory. Pay attention to the
-Basic class and Basic.Consume method - these were the primary test vehicles
-for this generator. *** NOTE *** These files do not represent any current or
-future version of the AMQP specification - do not use in production!
-
-Folders:
---------
-org/apache/qpid/gentools/: Source.
-xml-src/: Test AMQP specification files.
-templ.java/: Templates for java code generation.
-out.java/: Output folder for generated Java files (will be created with use
- of -j flag on command-line).
-templ.cpp/: (Future:) Templates for C++ code generation.
-out.cpp/: Output folder for generated C++ files (will be created with use
- of -c flag on command-line).
-
-For a more detaild description of the generator, see the Qpid Wiki
-(http://cwiki.apache.org/qpid/multiple-amqp-version-support.html).
-
-Please send comments and bugs to me (kim.vdriet [at] redhat.com) or via the
-Apache Qpid list (dev [at] qpid.apache.org).
-
-Kim van der Riet
diff --git a/gentools/build b/gentools/build
deleted file mode 100755
index a18a984dff..0000000000
--- a/gentools/build
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-#
-# 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.
-#
-#
-
-
-cd src
-echo "--------- Building gentools ----------"
-echo "Clearing out old build files..."
-for f in org/apache/qpid/gentools/*.class; do
- if [ -e $f ]; then
- rm $f
- fi
-done
-echo "Compiling..."
-javac -source=1.5 -target=1.5 org/apache/qpid/gentools/*.java
-echo "Done. Try it out..."
-java org.apache.qpid.gentools.Main
-echo "--------- Building gentools completed ----------"
-cd ..
diff --git a/gentools/build.xml b/gentools/build.xml
deleted file mode 100644
index f6760a215e..0000000000
--- a/gentools/build.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
- -
- - 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.
- -
- -->
-<project name="gentools" default="compile">
- <property name="src" location="src" />
-
- <property name="java.source" value="1.5"/>
- <property name="java.target" value="1.5"/>
-
- <target name="compile">
- <javac srcdir="${src}" source="${java.source}" target="${java.target}" fork="true" debug="on" includeantruntime="false">
- <classpath>
- <fileset dir="${src}/../lib">
- <include name="**/*.jar"/>
- </fileset>
- </classpath>
- </javac>
- </target>
-
- <target name="clean">
- <delete>
- <fileset dir="${src}/org/apache/qpid/gentools" includes="*.class" />
- </delete>
- </target>
-
-</project>
diff --git a/gentools/lib/LICENSE b/gentools/lib/LICENSE
deleted file mode 100644
index e69de29bb2..0000000000
--- a/gentools/lib/LICENSE
+++ /dev/null
diff --git a/gentools/lib/NOTICE b/gentools/lib/NOTICE
deleted file mode 100644
index e69de29bb2..0000000000
--- a/gentools/lib/NOTICE
+++ /dev/null
diff --git a/gentools/lib/README.txt b/gentools/lib/README.txt
deleted file mode 100644
index e69de29bb2..0000000000
--- a/gentools/lib/README.txt
+++ /dev/null
diff --git a/gentools/lib/velocity-1.4.jar b/gentools/lib/velocity-1.4.jar
deleted file mode 100644
index 04ec9d2f85..0000000000
--- a/gentools/lib/velocity-1.4.jar
+++ /dev/null
Binary files differ
diff --git a/gentools/lib/velocity-dep-1.4.jar b/gentools/lib/velocity-dep-1.4.jar
deleted file mode 100644
index 375712b0e8..0000000000
--- a/gentools/lib/velocity-dep-1.4.jar
+++ /dev/null
Binary files differ
diff --git a/gentools/src/org/apache/qpid/gentools/AmqpClass.java b/gentools/src/org/apache/qpid/gentools/AmqpClass.java
deleted file mode 100644
index 26195da2e3..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpClass.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- *
- * 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 org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.PrintStream;
-import java.util.Collection;
-
-public class AmqpClass implements Printable, NodeAware
-{
-
- 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
deleted file mode 100644
index a27a50d07e..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *
- * 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.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
deleted file mode 100644
index df5bc6c362..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpConstant.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- *
- * 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.io.PrintStream;
-import java.util.TreeMap;
-
-/**
- * @author kpvdr
- * Class to represent the &lt;constant&gt; 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 &lt;constant&gt; 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>
-{
- /**
- * Constant name as defined by the name attribute of the &lt;constant&gt; declaration.
- */
- private final String _name;
-
- /**
- * Set of versions for which this constant name is defined.
- */
- private final AmqpVersionSet _versionSet;
-
- /**
- * Constructor
- *
- * @param name Constant name as defined by the name attribute of the &lt;constant&gt; declaration.
- * @param value Constant value as defined by the value attribute of the &lt;constant&gt; declaration.
- * @param version AMQP version for which this constant is defined
- */
- public AmqpConstant(String name, String value, AmqpVersion version)
- {
- _name = name;
- _versionSet = new AmqpVersionSet(version);
- AmqpVersionSet valueVersionSet = new AmqpVersionSet(version);
- put(value, valueVersionSet);
- }
-
-
- /**
- * Get the name of this constant.
- *
- * @return Name of this constant, being the name attribute of the &lt;constant&gt; declaration
- * represented by this class.
- */
- public String getName()
- {
- 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 &lt;constant&gt; declaration
- * represented by this class.
- * @throws AmqpTypeMappingException when a value is requested for a version for which it is not
- * defined in the AMQP specifications.
- */
- public String getStringValue(AmqpVersion version)
- throws AmqpTypeMappingException
- {
- for (String thisValue : keySet())
- {
- AmqpVersionSet versionSet = get(thisValue);
- if (versionSet.contains(version))
- {
- return thisValue;
- }
- }
- 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 &lt;constant&gt; declaration
- * represented by this class.
- * @throws AmqpTypeMappingException when a value is requested for a version for which it is not
- * defined in the AMQP specifications.
- */
- public int getIntegerValue(AmqpVersion version)
- 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 &lt;constant&gt; declaration
- * represented by this class.
- * @throws AmqpTypeMappingException when a value is requested for a version for which it is not
- * defined in the AMQP specifications.
- */
- public double getDoubleValue(AmqpVersion version)
- 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;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Comparable#compareTo(java.lang.Object)
- */
-
- public int compareTo(AmqpConstant other)
- {
- int res = getName().compareTo(other.getName());
- if (res != 0)
- {
- return res;
- }
- return getVersionSet().compareTo(other.getVersionSet());
- }
-
- /* (non-Javadoc)
- * @see org.apache.qpid.gentools.VersionConsistencyCheck#isVersionConsistent(org.apache.qpid.gentools.AmqpVersionSet)
- */
- public boolean isVersionConsistent(AmqpVersionSet globalVersionSet)
- {
- if (size() != 1)
- {
- return false;
- }
- return get(firstKey()).equals(globalVersionSet);
- }
-
- /* (non-Javadoc)
- * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int)
- */
- public void print(PrintStream out, int marginSize, int tabSize)
- {
- String margin = Utils.createSpaces(marginSize);
- String tab = Utils.createSpaces(tabSize);
- if (size() == 1)
- {
- out.println(margin + tab + "[C] " + getName() + " = \"" + firstKey() + "\" " + getVersionSet());
- }
- else
- {
- out.println(margin + tab + "[C] " + getName() + ": " + getVersionSet());
- for (String thisValue : keySet())
- {
- 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
deleted file mode 100644
index ab8b8be61e..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- *
- * 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 org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.PrintStream;
-import java.util.Iterator;
-import java.util.TreeSet;
-
-/**
- * @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.
- */
-@SuppressWarnings("serial")
-public class AmqpConstantSet implements Printable, NodeAware //, Comparable<AmqpConstantSet>
-{
- private final LanguageConverter _converter;
- private final TreeSet<AmqpConstant> _constants = new TreeSet<AmqpConstant>();
- private final AmqpVersionSet _versionSet = new AmqpVersionSet();
-
- public AmqpConstantSet(LanguageConverter converter)
- {
- _converter = converter;
-
- }
-
- /* (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
- {
- _versionSet.add(version);
- NodeList nodeList = node.getChildNodes();
- for (int i = 0; i < nodeList.getLength(); i++)
- {
- Node childNode = nodeList.item(i);
- if (childNode.getNodeName().compareTo(Utils.ELEMENT_CONSTANT) == 0)
- {
- 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 = _constants.iterator();
- while (cItr.hasNext() && !foundName)
- {
- AmqpConstant thisConstant = cItr.next();
- if (name.compareTo(thisConstant.getName()) == 0)
- {
- foundName = true;
- thisConstant.getVersionSet().add(version);
- // Now, find the value in the map
- boolean foundValue = false;
- for (String thisValue : thisConstant.keySet())
- {
- if (value.compareTo(thisValue) == 0)
- {
- foundValue = true;
- // Add this version to existing version set.
- AmqpVersionSet versionSet = thisConstant.get(thisValue);
- versionSet.add(version);
- }
- }
- // Check that the value was found - if not, add it
- if (!foundValue)
- {
- thisConstant.put(value, new AmqpVersionSet(version));
- }
- }
- }
- // Check that the name was found - if not, add it
- if (!foundName)
- {
- _constants.add(new AmqpConstant(name, value, version));
- }
- }
- }
- return true;
- }
-
- /* (non-Javadoc)
- * @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 : _constants)
- {
- thisAmqpConstant.print(out, marginSize, tabSize);
- }
- }
-
- /* (non-Javadoc)
- * @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()
- {
- 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
deleted file mode 100644
index ba8552a6a6..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpDomain.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *
- * 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.io.PrintStream;
-import java.util.TreeMap;
-
-@SuppressWarnings("serial")
-public class AmqpDomain extends TreeMap<String, AmqpVersionSet> implements Printable
-{
- private final String _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 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;
- }
-
-}
diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java b/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java
deleted file mode 100644
index 0cd9d214bd..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *
- * 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 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
-{
- private final LanguageConverter _converter;
-
- public AmqpDomainMap(LanguageConverter converter)
- {
- _converter = converter;
-
- }
-
- 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);
- }
- }
-
- 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
deleted file mode 100644
index e39550b96f..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *
- * 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.ArrayList;
-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;
- }
-}
diff --git a/gentools/src/org/apache/qpid/gentools/AmqpField.java b/gentools/src/org/apache/qpid/gentools/AmqpField.java
deleted file mode 100644
index 7c721cf913..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpField.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- *
- * 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 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
-{
-
- 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
deleted file mode 100644
index 0bb5e03a61..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- *
- * 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.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 implements VersionConsistencyCheck
-{
-
- 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
deleted file mode 100644
index 5993a1b715..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *
- * 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.ArrayList;
-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;
- }
-}
diff --git a/gentools/src/org/apache/qpid/gentools/AmqpMethod.java b/gentools/src/org/apache/qpid/gentools/AmqpMethod.java
deleted file mode 100644
index 4ec39b209e..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpMethod.java
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- *
- * 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 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
-{
- 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
deleted file mode 100644
index d98dab4a39..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * 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.TreeMap;
-
-@SuppressWarnings("serial")
-public class AmqpMethodMap extends TreeMap<String, AmqpMethod>
-{
- 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
deleted file mode 100644
index 45f0adb18d..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpModel.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *
- * 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 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
-{
- 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
deleted file mode 100644
index 0633eff1e1..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- * 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.Iterator;
-import java.util.Set;
-import java.util.TreeMap;
-
-@SuppressWarnings("serial")
-public class AmqpOrdinalFieldMap extends TreeMap<Integer, String[]> implements Comparable
-{
-
-
- public int compareTo(Object obj)
- {
- AmqpOrdinalFieldMap o = (AmqpOrdinalFieldMap) obj;
- Set<Integer> thisKeySet = keySet();
- Set<Integer> oKeySet = o.keySet();
- if (!thisKeySet.equals(oKeySet)) // Not equal, but why?
- {
- // Size difference
- int sizeDiff = thisKeySet.size() - oKeySet.size(); // -ve if this < other
- if (sizeDiff != 0)
- {
- return sizeDiff;
- }
- // Conetent difference
- Iterator<Integer> itr = thisKeySet.iterator();
- Iterator<Integer> oItr = oKeySet.iterator();
- while (itr.hasNext() && oItr.hasNext())
- {
- int diff = itr.next() - oItr.next(); // -ve if this < other
- if (diff != 0)
- {
- return diff;
- }
- }
- // We should never get here...
- System.err.println("AmqpOrdinalFieldMap.compareTo(): " +
- "WARNING - unable to find cause of keySet difference.");
- }
- // Keys are equal, now check the String[]s
- Iterator<Integer> itr = thisKeySet.iterator();
- Iterator<Integer> oItr = oKeySet.iterator();
- while (itr.hasNext() && oItr.hasNext())
- {
- String[] thisPair = get(itr.next());
- String[] oPair = o.get(oItr.next());
- // Size difference
- int sizeDiff = thisPair.length - oPair.length; // -ve if this < other
- if (sizeDiff != 0)
- {
- return sizeDiff;
- }
- // Conetent difference
- for (int i = 0; i < thisPair.length; i++)
- {
- int diff = thisPair[i].compareTo(oPair[i]);
- if (diff != 0)
- {
- return diff;
- }
- }
- }
- return 0;
- }
-
- 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
deleted file mode 100644
index fede88631a..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *
- * 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.ArrayList;
-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 int getOrdinal(AmqpVersion version)
- throws AmqpTypeMappingException
- {
- 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;
- }
-}
diff --git a/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java b/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
deleted file mode 100644
index 10978d0e4a..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *
- * 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.TreeMap;
-
-@SuppressWarnings("serial")
-public class AmqpOverloadedParameterMap extends TreeMap<AmqpOrdinalFieldMap, AmqpVersionSet>
-{
-
-}
diff --git a/gentools/src/org/apache/qpid/gentools/AmqpParseException.java b/gentools/src/org/apache/qpid/gentools/AmqpParseException.java
deleted file mode 100644
index 3f3d4611fc..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpParseException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *
- * 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;
-
-@SuppressWarnings("serial")
-public class AmqpParseException extends RuntimeException
-{
- 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
deleted file mode 100644
index 1ac09ea453..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *
- * 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;
-
-@SuppressWarnings("serial")
-public class AmqpTemplateException extends RuntimeException
-{
- 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
deleted file mode 100644
index 127a8835b0..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *
- * 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;
-
-@SuppressWarnings("serial")
-public class AmqpTypeMappingException extends RuntimeException
-{
- 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
deleted file mode 100644
index dbeef1b895..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpVersion.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *
- * 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 AmqpVersion implements Comparable<AmqpVersion>
-{
- private final int _major;
- private final int _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
deleted file mode 100644
index 6419e23a1e..0000000000
--- a/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *
- * 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.io.PrintStream;
-import java.util.Iterator;
-import java.util.TreeSet;
-
-@SuppressWarnings("serial")
-public class AmqpVersionSet extends TreeSet<AmqpVersion> implements Printable, Comparable<AmqpVersionSet>
-{
- public AmqpVersionSet()
- {
- super();
- }
-
- public AmqpVersionSet(AmqpVersion version)
- {
- super();
- add(version);
- }
-
- public AmqpVersion find(AmqpVersion version)
- {
- 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 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())
- {
- AmqpVersion version = vItr.next();
- 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
deleted file mode 100644
index d85510ee98..0000000000
--- a/gentools/src/org/apache/qpid/gentools/BitFieldGenerateMethod.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index 641f50c3f8..0000000000
--- a/gentools/src/org/apache/qpid/gentools/CommandGenerateMethod.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index 9ab7eb178b..0000000000
--- a/gentools/src/org/apache/qpid/gentools/ConsolidatedField.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *
- * 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;
-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
deleted file mode 100644
index 4f58cba34e..0000000000
--- a/gentools/src/org/apache/qpid/gentools/CppGenerator.java
+++ /dev/null
@@ -1,1716 +0,0 @@
-/*
- *
- * 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.io.File;
-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;
-
- /**
- * 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"};
-
- /**
- * 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
- * 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. 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()
- {
- 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
- "buffer.putLongLong(#)", // encodeExpression
- "# = 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.putShortString(#)", // encodeExpression
- "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.putLongLong(#)", // encodeExpression
- "buffer.getLongLong(#)")); // decodeExpression
- }
-
-
- public boolean isQuietFlag()
- {
- return quietFlag;
- }
-
- public void setQuietFlag(boolean quietFlag)
- {
- 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 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)
- {
- 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, 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.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.getFieldMap().size() > 0 ? " buffer" : "";
- }
- if (token.compareTo("${hv_latest_major}") == 0)
- {
- return String.valueOf(getVersionSet().last().getMajor());
- }
- if (token.compareTo("${hv_latest_minor}") == 0)
- {
- 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);
- }
- else if (token.compareTo("${cph_handler_pointer_get_method}") == 0)
- {
- 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);
- }
- else if (token.compareTo("${sph_handler_pointer_defn}") == 0)
- {
- codeSnippet = generateHandlerPointerDefinitions(model, true, 4);
- }
- else if (token.compareTo("${sph_handler_pointer_get_method}") == 0)
- {
- codeSnippet = generateHandlerPointerGetMethods(model, true, 4);
- }
-
- // amqp_methods.h/cpp
- else if (token.compareTo("${mh_method_body_class_indlude}") == 0)
- {
- codeSnippet = generateMethodBodyIncludeList(model, 0);
- }
- else if (token.compareTo("${mh_method_body_class_instance}") == 0)
- {
- codeSnippet = generateMethodBodyInstances(model, 0);
- }
- else if (token.compareTo("${mc_create_method_body_map_entry}") == 0)
- {
- 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)
- {
- 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("${cpc_method_body_include}") == 0)
- {
- codeSnippet = generateMethodBodyIncludes(thisClass, 0);
- }
- else if (token.compareTo("${spc_method_body_include}") == 0)
- {
- codeSnippet = generateMethodBodyIncludes(thisClass, 0);
- }
- else if (token.compareTo("${mc_method_body_include}") == 0)
- {
- 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 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 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);
- }
-
- else // Oops!
- {
- throw new AmqpTemplateException("Template token " + token + " unknown.");
- }
- sb.insert(listMarkerStartIndex, codeSnippet);
- }
-
- // === 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)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
- for (AmqpConstant thisConstant : constantSet.getContstants())
- {
- if (thisConstant.isVersionConsistent(getVersionSet()))
- {
- // return a constant
- String value = thisConstant.firstKey();
- sb.append(indent + "static const char* " + thisConstant.getName() + "() { return \"" +
- thisConstant.firstKey() + "\"; }" + CR);
- if (Utils.containsOnlyDigits(value))
- {
- sb.append(indent + "static int " + thisConstant.getName() + "AsInt() { return " +
- thisConstant.firstKey() + "; }" + CR);
- }
- if (Utils.containsOnlyDigitsAndDecimal(value))
- {
- sb.append(indent + "static double " + thisConstant.getName() + "AsDouble() { return (double)" +
- thisConstant.firstKey() + "; }" + CR);
- }
- sb.append(CR);
- }
- else
- {
- // Return version-specific constant
- 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);
- }
- }
- return sb.toString();
- }
-
- protected String generateVersionDependentGet(AmqpConstant constant, 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 + 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);
- if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(thisValue))
- {
- sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType,
- indentSize + (2 * tabSize), tabSize));
- }
- else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(thisValue))
- {
- 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 + "}" + 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.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)
- {
- String indent = Utils.createSpaces(indentSize);
- String tab = Utils.createSpaces(tabSize);
- StringBuffer sb = new StringBuffer();
- 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.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)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
- String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations";
- for (String thisClassName : model.getClassMap().keySet())
- {
- 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)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
- String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations";
- for (String thisClassName : model.getClassMap().keySet())
- {
- 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();
- String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy";
- 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.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);
- sb.append(indent + "out(out)");
- 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();
- if (thisClass != null)
- {
- sb.append(generateClassMethodBodyInclude(thisClass, indentSize));
- }
- else
- {
- for (String thisClassName : getModel().getClassMap().keySet())
- {
- thisClass = getModel().getClassMap().get(thisClassName);
- sb.append(generateClassMethodBodyInclude(thisClass, indentSize));
- }
- }
- return sb.toString();
- }
-
- protected String generateClassMethodBodyInclude(AmqpClass thisClass, int indentSize)
- {
- StringBuffer sb = new StringBuffer();
- String indent = Utils.createSpaces(indentSize);
- 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 = 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)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
-
- if (version == null)
- {
- 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)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
-
- if (version == null)
- {
- version = getVersionSet().first();
- }
- AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this);
- boolean firstFlag = true;
- for (Integer thisOrdinal : ordinalFieldMap.keySet())
- {
- String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal);
- 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);
- firstFlag = false;
- }
- 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)
- {
- String indent = Utils.createSpaces(indentSize);
- String tab = Utils.createSpaces(tabSize);
- StringBuffer sb = new StringBuffer();
- 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)
- {
- String indent = Utils.createSpaces(indentSize);
- String tab = Utils.createSpaces(tabSize);
- StringBuffer sb = new StringBuffer();
-
- if (method.getServerMethodFlagMap().size() > 0) // At least one AMQP version defines this method as a server method
- {
- Iterator<Boolean> bItr = method.getServerMethodFlagMap().keySet().iterator();
- while (bItr.hasNext())
- {
- if (bItr.next()) // This is a server operation
- {
- 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.getFieldMap(), version, false, false, indentSize + 4 * tabSize));
- sb.append(indent + tab + tab + tab + tab);
- }
- sb.append(");" + CR);
- sb.append(indent + "}" + CR);
- }
- }
- }
- 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.getClassMap().keySet())
- {
- AmqpClass thisClass = model.getClassMap().get(thisClassName);
- 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();
- }
-
- protected String generateMethodBodyInstances(AmqpModel model, int indentSize)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
-
- for (String thisClassName : model.getClassMap().keySet())
- {
- AmqpClass thisClass = model.getClassMap().get(thisClassName);
- for (String thisMethodName : thisClass.getMethodMap().keySet())
- {
- 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();
- }
-
- protected String generateMethodBodyMapEntry(AmqpModel model, int indentSize)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
-
- for (AmqpVersion version : getVersionSet())
- {
- for (String thisClassName : model.getClassMap().keySet())
- {
- AmqpClass thisClass = model.getClassMap().get(thisClassName);
- for (String thisMethodName : thisClass.getMethodMap().keySet())
- {
- AmqpMethod method = thisClass.getMethodMap().get(thisMethodName);
- String namespace = method.isVersionConsistent(getVersionSet()) ? "" : version.namespace() + "::";
- try
- {
- 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);
- }
- catch (AmqpTypeMappingException e)
- {
- } // ignore
- }
- }
- }
-
- return sb.toString();
- }
-
- // Helper functions
-
- 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 + "_\".");
- }
- 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 + "_\".");
- }
- 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();
- }
-
- 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
deleted file mode 100644
index 9fc81dd428..0000000000
--- a/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- *
- * 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.io.File;
-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 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
- {
- String codeSnippet;
- int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line
- String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr
- int tokStart = tline.indexOf('$');
- String token = tline.substring(tokStart).trim();
- sb.delete(listMarkerStartIndex, lend);
-
- // TODO: Add in tokens and calls to their corresponding generator methods here...
- if (token.compareTo("${??????????}") == 0)
- {
- codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present.
-// codeSnippet = generateConstantGetMethods(constantSet, 4, 4);
- }
-
- else // Oops!
- {
- throw new AmqpTemplateException("Template token " + token + " unknown.");
- }
- sb.insert(listMarkerStartIndex, codeSnippet);
- }
-
- @Override
- protected void processFieldList(StringBuffer sb, int listMarkerStartIndex,
- int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version)
- {
- 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 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();
- }
-
-
- 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
deleted file mode 100644
index 8b0bb99b41..0000000000
--- a/gentools/src/org/apache/qpid/gentools/GenerateMethod.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index 5d6e7be527..0000000000
--- a/gentools/src/org/apache/qpid/gentools/Generator.java
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- *
- * 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 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.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.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 _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);
-
-
- 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 version specific template files in directory: " + versionTemplateDirectory.getAbsoluteFile());
-
- if (versionTemplateDirectory.exists())
- {
- versionTemplateFiles = versionTemplateDirectory.listFiles(_tmplFileFilter);
- }
-
- if(templateFiles != null)
- {
- for (File templateFile : templateFiles)
- {
- System.out.println(type.getName() + " template file(s):");
- System.out.println(" " + templateFile.getCanonicalPath());
- typeTemplates.add(new NamedTemplate(type.getName(), templateFile));
- }
- }
-
- if(versionTemplateFiles != null)
- {
- 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));
- }
- }
-
- }
- }
-
- 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"));
-
- File outputFile = new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename);
- outputFile.getParentFile().mkdirs();
- FileWriter outputFileWriter = new FileWriter(outputFile);
-
- 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, _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)
- {
- 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
deleted file mode 100644
index 7730fca1bd..0000000000
--- a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java
+++ /dev/null
@@ -1,1826 +0,0 @@
-/*
- *
- * 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.io.File;
-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
- {
- 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, 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
- 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();
- sb.delete(listMarkerStartIndex, lend);
-
- if (token.compareTo("${const_get_method}") == 0)
- {
- 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);
- }
- }
- 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)
- {
- String indent = Utils.createSpaces(indentSize);
- StringBuffer sb = new StringBuffer();
-
- for (AmqpConstant constant : constantSet.getContstants())
- {
-
- if (constant.isVersionConsistent(constantSet.getVersionSet()))
- {
- // return a constant
- String value = constant.firstKey();
- if (Utils.containsOnlyDigits(value))
- {
- sb.append(indent + "public static final int " + constant.getName() + " = " +
- constant.firstKey() + ";" + CR);
- }
- else if (Utils.containsOnlyDigitsAndDecimal(value))
- {
- sb.append(indent + "public static double " + constant.getName() + " = " +
- constant.firstKey() + "; " + CR);
- }
- else
- {
- sb.append(indent + "public static String " + constant.getName() + " = " +
- constant.firstKey() + "\"; " + CR);
-
- }
- sb.append(CR);
- }
- else
- {
- // Return version-specific constant
- 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();
- }
-
- protected String generateVersionDependentGet(AmqpConstant constant,
- 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.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())
- {
- String value = sItr.next();
- AmqpVersionSet versionSet = constant.get(value);
- sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) +
- ")" + CR);
- sb.append(indent + tab + "{" + CR);
- if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(value))
- {
- sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType,
- indentSize + (2 * tabSize), tabSize));
- }
- else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(value))
- {
- 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 + "}" + CR);
- first = false;
- }
- sb.append(indent + tab + "else" + CR);
- sb.append(indent + tab + "{" + CR);
- sb.append(indent + tab + tab + "throw new AMQProtocolVersionException(\"Constant \\\"" +
- 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();
- }
-
- protected String generateConstantDeclarationException(String name, String methodReturnType,
- 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);
- 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.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
deleted file mode 100644
index 5e692d86e7..0000000000
--- a/gentools/src/org/apache/qpid/gentools/LanguageConverter.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *
- * 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 LanguageConverter
-{
-
-// 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
deleted file mode 100644
index c0584f7ca7..0000000000
--- a/gentools/src/org/apache/qpid/gentools/Main.java
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- *
- * 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 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 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 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 GeneratedLanguage _generatorLang;
- private ArrayList<String> xmlFiles;
-
- public Main()
- {
- xmlFiles = new ArrayList<String>();
- }
-
- public void run(String[] args)
- throws Exception,
- SAXException,
- AmqpParseException,
- AmqpTypeMappingException,
- AmqpTemplateException,
- TargetDirectoryException,
- IllegalAccessException,
- InvocationTargetException, ParserConfigurationException
- {
-
- // 0. Initialize
- outDir = DEFAULT_OUTPUT_DIR;
- tmplDir = null;
- _generatorLang = GeneratedLanguage.CPP; // Default generation language
- xmlFiles.clear();
- processArgs(args);
-
- if (tmplDir == null)
- {
- tmplDir = _generatorLang.getDefaultTemplateDirectory();
- }
-
-
- generator = _generatorLang.newGenerator();
- generator.setTemplateDirectory(tmplDir);
- generator.setOutputDirectory(outDir);
-
- // 1. Suck in all the XML spec files provided on the command line
- analyzeXML();
-
- 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++)
- {
- String arg = args[i];
- if (arg.charAt(0) == '-')
- {
- switch (arg.charAt(1))
- {
- case'c':
- case'C':
- _generatorLang = GeneratedLanguage.CPP;
- break;
- case'j':
- case'J':
- _generatorLang = GeneratedLanguage.JAVA;
- break;
- case'n':
- case'N':
- _generatorLang = GeneratedLanguage.DOTNET;
- break;
- case'o':
- case'O':
- if (++i < args.length)
- {
- outDir = args[i];
- }
- break;
- case't':
- case'T':
- if (++i < args.length)
- {
- tmplDir = args[i];
- }
- break;
- }
- }
- else
- {
- xmlFiles.add(args[i]);
- }
- }
- }
-
- private void analyzeXML()
- throws IOException, SAXException, AmqpParseException, AmqpTypeMappingException, ParserConfigurationException
- {
- DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-
- System.out.println("XML files: " + xmlFiles);
- for (String filename : xmlFiles)
- {
- File f = new File(filename);
- if (f.exists())
- {
- // 1a. Initialize dom
- 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() + ".");
- 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();
-// System.out.println("*** Debug output ***");
-// System.out.println();
-// versionSet.print(System.out, 0, 2); // List of loaded versions
-// System.out.println();
-// constants.print(System.out, 0, 2); // List of constants
-// System.out.println();
-// domainMap.print(System.out, 0, 2); // List of domains
-// System.out.println();
-// model.print(System.out, 0, 2); // Internal version map model
-// System.out.println();
-// 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();
- }
- 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: \"" + 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
deleted file mode 100644
index ffeefed900..0000000000
--- a/gentools/src/org/apache/qpid/gentools/MangledGenerateMethod.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index f832da75ad..0000000000
--- a/gentools/src/org/apache/qpid/gentools/NodeAware.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *
- * 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 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.
- */
-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;
-}
diff --git a/gentools/src/org/apache/qpid/gentools/Printable.java b/gentools/src/org/apache/qpid/gentools/Printable.java
deleted file mode 100644
index aa13df7b68..0000000000
--- a/gentools/src/org/apache/qpid/gentools/Printable.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *
- * 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.io.PrintStream;
-
-public interface Printable
-{
- 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
deleted file mode 100644
index 8e1af1c551..0000000000
--- a/gentools/src/org/apache/qpid/gentools/SingleVersionClass.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index b795663d15..0000000000
--- a/gentools/src/org/apache/qpid/gentools/SingleVersionField.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index 59a6d9e28a..0000000000
--- a/gentools/src/org/apache/qpid/gentools/SingleVersionMethod.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index 22b416e45a..0000000000
--- a/gentools/src/org/apache/qpid/gentools/SingleVersionModel.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- *
- * 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
deleted file mode 100644
index 39ce666288..0000000000
--- a/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *
- * 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;
-
-@SuppressWarnings("serial")
-public class TargetDirectoryException extends RuntimeException
-{
- 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
deleted file mode 100644
index 1cedaeea12..0000000000
--- a/gentools/src/org/apache/qpid/gentools/Utils.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- *
- * 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 org.w3c.dom.Attr;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public class Utils
-{
- 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 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.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++)
- {
- if (!Character.isDigit(str.charAt(i)))
- {
- foundNonDigit = true;
- }
- }
- 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++)
- {
- char ch = str.charAt(i);
- if (!(Character.isDigit(ch) || ch == '.'))
- {
- foundNonDigit = true;
- }
- else if (ch == '.')
- {
- decimalCntr++;
- }
- }
- return !foundNonDigit && decimalCntr < 2;
- }
-}
diff --git a/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java b/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java
deleted file mode 100644
index a9cdd56e88..0000000000
--- a/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- * 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 VersionConsistencyCheck
-{
- public boolean isVersionConsistent(AmqpVersionSet globalVersionSet);
-}
diff --git a/gentools/templ.cpp/method/MethodBodyClass.h.tmpl b/gentools/templ.cpp/method/MethodBodyClass.h.tmpl
deleted file mode 100644
index 5819a9cf9c..0000000000
--- a/gentools/templ.cpp/method/MethodBodyClass.h.tmpl
+++ /dev/null
@@ -1,112 +0,0 @@
-&{${CLASS}${METHOD}Body.h}
-/*
- *
- * 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}
- */
-
-#ifndef qpid_framing_${CLASS}${METHOD}Body__
-#define qpid_framing_${CLASS}${METHOD}Body__
-
-#include <string>
-#include <sstream>
-
-#include <amqp_types.h>
-#include <AMQMethodBody.h>
-#include <Buffer.h>
-#include <FieldTable.h>
-
-namespace qpid
-{
-namespace framing
-{
-${version_namespace_start}
-
-class ${CLASS}${METHOD}Body : public AMQMethodBody
-{
- // Method field declarations
-
-%{FLIST} ${mb_field_declaration}
-
-
-public:
- typedef boost::shared_ptr<${CLASS}${METHOD}Body> shared_ptr;
-
- // Constructors and destructors
-
-${mb_constructor_with_initializers}
-
- inline ${CLASS}${METHOD}Body(u_int8_t major, u_int8_t minor): AMQMethodBody(major, minor) {}
- inline ${CLASS}${METHOD}Body(ProtocolVersion& version): AMQMethodBody(version) {}
- virtual ~${CLASS}${METHOD}Body() {}
-
- // Attribute get methods
-
-%{FLIST} ${mb_field_get_method}
-
- // Helper methods
-
- inline void print(std::ostream& out) const
- {
- out << "${CLASS}${METHOD}: ";
-%{FLIST} ${mb_field_print}
- }
-
- inline u_int16_t amqpClassId() const
- {
- return ${CLASS_ID_INIT};
- }
-
- inline u_int16_t amqpMethodId() const
- {
- return ${METHOD_ID_INIT};
- }
-
- inline u_int32_t bodySize() const
- {
- u_int32_t size = 0;
-%{FLIST} ${mb_body_size}
- return size;
- }
-
- inline void encodeContent(Buffer&${mb_buffer_param}) const
- {
-%{FLIST} ${mb_encode}
- }
-
- inline void decodeContent(Buffer&${mb_buffer_param})
- {
-%{FLIST} ${mb_decode}
- }
-
-${mb_server_operation_invoke}
-
-}; // class ${CLASS}${METHOD}Body
-
-${version_namespace_end}
-} // namespace framing
-} // namespace qpid
-
-#endif
-
diff --git a/gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl b/gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl
deleted file mode 100644
index a9fb0e0f69..0000000000
--- a/gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl
+++ /dev/null
@@ -1,82 +0,0 @@
-&{AMQP_ClientOperations.h}
-/*
- *
- * 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}
- */
-
-#ifndef qpid_framing_AMQP_ClientOperations__
-#define qpid_framing_AMQP_ClientOperations__
-
-#include <sstream>
-
-#include <FieldTable.h>
-#include <ProtocolVersion.h>
-#include <ProtocolVersionException.h>
-
-namespace qpid {
-namespace framing {
-
-class AMQP_ClientProxy;
-
-class AMQP_ClientOperations
-{
-protected:
- ProtocolVersion version;
- AMQP_ClientOperations() {}
-
-public:
- AMQP_ClientOperations(u_int8_t major, u_int8_t minor) : version(major, minor) {}
- AMQP_ClientOperations(ProtocolVersion& version) : version(version) {}
- virtual ~AMQP_ClientOperations() {}
-
- inline u_int8_t getMajor() const { return version.getMajor(); }
- inline u_int8_t getMinor() const { return version.getMinor(); }
- inline const ProtocolVersion& getVersion() const { return version; }
- inline bool isVersion(u_int8_t _major, u_int8_t _minor) const
- {
- return version.equals(_major, _minor);
- }
- inline bool isVersion(ProtocolVersion& _version) const
- {
- return version.equals(_version);
- }
-
- // Include framing constant declarations
- #include <AMQP_Constants.h>
-
- // Inner classes
-
-%{CLIST} ${coh_inner_class}
-
- // Method handler get methods
-
-%{CLIST} ${coh_method_handler_get_method}
-
-}; /* class AMQP_ClientOperations */
-
-} /* namespace framing */
-} /* namespace qpid */
-
-#endif
diff --git a/gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl b/gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl
deleted file mode 100644
index 8cca6e5cec..0000000000
--- a/gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl
+++ /dev/null
@@ -1,52 +0,0 @@
-&{AMQP_ClientProxy.cpp}
-/*
- *
- * 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}
- */
-
-#include <sstream>
-
-#include <AMQP_ClientProxy.h>
-#include <AMQFrame.h>
-%{MLIST} ${cpc_method_body_include}
-
-namespace qpid {
-namespace framing {
-
-AMQP_ClientProxy::AMQP_ClientProxy(OutputHandler* out, u_int8_t major, u_int8_t minor) :
-%{CLIST} ${cpc_constructor_initializer}
-
-{}
-
- // Inner class instance get methods
-
-%{CLIST} ${cpc_inner_class_get_method}
-
- // Inner class implementation
-
-%{CLIST} ${cpc_inner_class_impl}
-
-} /* namespace framing */
-} /* namespace qpid */
diff --git a/gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl b/gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl
deleted file mode 100644
index 0653ed7186..0000000000
--- a/gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl
+++ /dev/null
@@ -1,75 +0,0 @@
-&{AMQP_ClientProxy.h}
-/*
- *
- * 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}
- */
-
-#ifndef qpid_framing_AMQP_ClientProxy__
-#define qpid_framing_AMQP_ClientProxy__
-
-#include <AMQP_ClientOperations.h>
-#include <FieldTable.h>
-#include <OutputHandler.h>
-
-namespace qpid {
-namespace framing {
-
-class AMQP_ClientProxy : public AMQP_ClientOperations
-{
-private:
-
- ProtocolVersion version;
- OutputHandler* out;
-%{CLIST} ${cph_handler_pointer_defn}
-
-public:
- AMQP_ClientProxy(OutputHandler* out, u_int8_t major, u_int8_t minor);
- ProtocolVersion& getProtocolVersion() {return version;}
- virtual ~AMQP_ClientProxy() {}
-
- // Get methods for handlers
-
-%{CLIST} ${cph_handler_pointer_get_method}
-
- // Inner class definitions
-
-%{CLIST} ${cph_inner_class_defn}
-
-private:
- // Inner class instances
-
-%{CLIST} ${cph_inner_class_instance}
-
-public:
- // Inner class instance get methods
-
-%{CLIST} ${cph_inner_class_get_method}
-
-}; /* class AMQP_ClientProxy */
-
-} /* namespace framing */
-} /* namespace qpid */
-
-#endif
diff --git a/gentools/templ.cpp/model/AMQP_Constants.h.tmpl b/gentools/templ.cpp/model/AMQP_Constants.h.tmpl
deleted file mode 100644
index 4631bc8de6..0000000000
--- a/gentools/templ.cpp/model/AMQP_Constants.h.tmpl
+++ /dev/null
@@ -1,34 +0,0 @@
-&{AMQP_Constants.h}
-/*
- *
- * 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}
- */
- // NOTE: This file is intended to be included within the class structure of both
- // the client and server operations classes. These need to have <sstream> included.
-
- // Constant getValue methods
-
-%{TLIST} ${ch_get_value_method}
- \ No newline at end of file
diff --git a/gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl b/gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl
deleted file mode 100644
index 9753b454ba..0000000000
--- a/gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl
+++ /dev/null
@@ -1,42 +0,0 @@
-&{AMQP_HighestVersion.h}
-/*
- *
- * 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}
- */
-#ifndef qpid_framing_highestProtocolVersion__
-#define qpid_framing_highestProtocolVersion__
-
-#include <ProtocolVersion.h>
-
-
-namespace qpid {
-namespace framing {
-
-static ProtocolVersion highestProtocolVersion(${hv_latest_major}, ${hv_latest_minor});
-
-} /* namespace framing */
-} /* namespace qpid */
-
-#endif
diff --git a/gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl b/gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl
deleted file mode 100644
index dc2a890c88..0000000000
--- a/gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl
+++ /dev/null
@@ -1,62 +0,0 @@
-&{AMQP_MethodVersionMap.cpp}
-/*
- *
- * 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}
- */
-
-#include <sstream>
-
-#include <AMQP_MethodVersionMap.h>
-
-namespace qpid
-{
-namespace framing
-{
-
-AMQP_MethodVersionMap::AMQP_MethodVersionMap()
-{
-%{CLIST} ${mc_create_method_body_map_entry}
-}
-
-AMQMethodBody* AMQP_MethodVersionMap::createMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor)
-{
- iterator itr = find(createMapKey(classId, methodId, major, minor));
- if (itr == end())
- {
- std::stringstream ss;
- ss << "Unable to find MethodBody class for classId = " << classId << ", methodId = " <<
- methodId << ", AMQ protocol version = " << major << "-" << minor << ".";
- throw ProtocolVersionException(ss.str());
- }
- return (itr->second)(major, minor);
-}
-
-u_int64_t AMQP_MethodVersionMap::createMapKey(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor)
-{
- return ((u_int64_t)classId<<48) + ((u_int64_t)methodId<<32) + ((u_int64_t)major<<16) + minor;
-}
-
-} /* namespace framing */
-} /* namespace qpid */
diff --git a/gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl b/gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl
deleted file mode 100644
index c197871d4b..0000000000
--- a/gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl
+++ /dev/null
@@ -1,57 +0,0 @@
-&{AMQP_MethodVersionMap.h}
-/*
- *
- * 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}
- */
-
-#ifndef qpid_framing_AMQP_MethodVersionMap__
-#define qpid_framing_AMQP_MethodVersionMap__
-
-#include <map>
-#include <AMQMethodBody.h>
-
-%{MLIST} ${mc_method_body_include}
-
-namespace qpid
-{
-namespace framing
-{
-
-template <class T> AMQMethodBody* createMethodBodyFn(u_int8_t major, u_int8_t minor) { return new T(major, minor); }
-typedef AMQMethodBody* (*fnPtr)(u_int8_t, u_int8_t);
-
-class AMQP_MethodVersionMap: public std::map<u_int64_t, fnPtr>
-{
-protected:
- u_int64_t createMapKey(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor);
-public:
- AMQP_MethodVersionMap();
- AMQMethodBody* createMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor);
-};
-
-} /* namespace framing */
-} /* namespace qpid */
-
-#endif
diff --git a/gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl b/gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl
deleted file mode 100644
index e87723667b..0000000000
--- a/gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl
+++ /dev/null
@@ -1,83 +0,0 @@
-&{AMQP_ServerOperations.h}
-/*
- *
- * 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}
- */
-
-#ifndef qpid_framing_AMQP_ServerOperations__
-#define qpid_framing_AMQP_ServerOperations__
-
-#include <sstream>
-
-#include <FieldTable.h>
-#include <ProtocolVersion.h>
-#include <ProtocolVersionException.h>
-
-namespace qpid {
-namespace framing {
-
-class AMQP_ServerProxy;
-class AMQP_ClientProxy;
-
-class AMQP_ServerOperations
-{
-protected:
- ProtocolVersion version;
- AMQP_ServerOperations() {}
-
-public:
- AMQP_ServerOperations(u_int8_t major, u_int8_t minor) : version(major, minor) {}
- AMQP_ServerOperations(ProtocolVersion& version) : version(version) {}
- virtual ~AMQP_ServerOperations() {}
-
- inline u_int8_t getMajor() const { return version.getMajor(); }
- inline u_int8_t getMinor() const { return version.getMinor(); }
- inline const ProtocolVersion& getVersion() const { return version; }
- inline bool isVersion(u_int8_t _major, u_int8_t _minor) const
- {
- return version.equals(_major, _minor);
- }
- inline bool isVersion(ProtocolVersion& _version) const
- {
- return version.equals(_version);
- }
-
- // Include framing constant declarations
- #include <AMQP_Constants.h>
-
- // Inner classes
-
-%{CLIST} ${soh_inner_class}
-
- // Method handler get methods
-
-%{CLIST} ${soh_method_handler_get_method}
-
-}; /* class AMQP_ServerOperations */
-
-} /* namespace framing */
-} /* namespace qpid */
-
-#endif
diff --git a/gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl b/gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl
deleted file mode 100644
index cce369f98b..0000000000
--- a/gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl
+++ /dev/null
@@ -1,51 +0,0 @@
-&{AMQP_ServerProxy.cpp}
-/*
- *
- * 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}
- */
-
-#include <sstream>
-
-#include <AMQP_ServerProxy.h>
-#include <AMQFrame.h>
-%{MLIST} ${spc_method_body_include}
-
-namespace qpid {
-namespace framing {
-
-AMQP_ServerProxy::AMQP_ServerProxy(OutputHandler* out, u_int8_t major, u_int8_t minor) :
-%{CLIST} ${spc_constructor_initializer}
-{}
-
- // Inner class instance get methods
-
-%{CLIST} ${spc_inner_class_get_method}
-
- // Inner class implementation
-
-%{CLIST} ${spc_inner_class_impl}
-
-} /* namespace framing */
-} /* namespace qpid */
diff --git a/gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl b/gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl
deleted file mode 100644
index fab29f2c60..0000000000
--- a/gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl
+++ /dev/null
@@ -1,74 +0,0 @@
-&{AMQP_ServerProxy.h}
-/*
- *
- * 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}
- */
-
-#ifndef qpid_framing_AMQP_ServerProxy__
-#define qpid_framing_AMQP_ServerProxy__
-
-#include <AMQP_ServerOperations.h>
-#include <FieldTable.h>
-#include <OutputHandler.h>
-
-namespace qpid {
-namespace framing {
-
-class AMQP_ServerProxy : public AMQP_ServerOperations
-{
-private:
- ProtocolVersion version;
- OutputHandler* out;
-%{CLIST} ${sph_handler_pointer_defn}
-
-public:
- AMQP_ServerProxy(OutputHandler* out, u_int8_t major, u_int8_t minor);
- ProtocolVersion& getProtocolVersion() {return version;}
- virtual ~AMQP_ServerProxy() {}
-
- // Get methods for handlers
-
-%{CLIST} ${sph_handler_pointer_get_method}
-
- // Inner class definitions
-
-%{CLIST} ${sph_inner_class_defn}
-
-private:
- // Inner class instances
-
-%{CLIST} ${sph_inner_class_instance}
-
-public:
- // Inner class instance get methods
-
-%{CLIST} ${sph_inner_class_get_method}
-
-}; /* class AMQP_ServerProxy */
-
-} /* namespace framing */
-} /* namespace qpid */
-
-#endif
diff --git a/gentools/templ.java/PropertyContentHeaderClass.tmpl b/gentools/templ.java/PropertyContentHeaderClass.tmpl
deleted file mode 100644
index ab6406b1fe..0000000000
--- a/gentools/templ.java/PropertyContentHeaderClass.tmpl
+++ /dev/null
@@ -1,208 +0,0 @@
-&{${CLASS}ContentHeaderProperties.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;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.mina.common.ByteBuffer;
-
-public class ${CLASS}ContentHeaderProperties implements ContentHeaderProperties
-{
- private static final Logger logger = LoggerFactory.getLogger(BasicContentHeaderProperties.class);
-
- /**
- * We store the encoded form when we decode the content header so that if we need to
- * write it out without modifying it we can do so without incurring the expense of
- * reencoding it.
- */
- private byte[] encodedBuffer;
-
- /**
- * Flag indicating whether the entire content header has been decoded yet.
- */
- private boolean decodedFlag = true;
-
- /**
- * We have some optimisations for partial decoding for maximum performance. The
- * headers are used in the broker for routing in some cases so we can decode that
- * separately.
- */
- private boolean decodedHeadersFlag = true;
-
- /**
- * We have some optimisations for partial decoding for maximum performance. The
- * content type is used by all clients to determine the message type.
- */
- private boolean decodedContentTypeFlag = true;
-
- /**
- * AMQP major and minor version of this instance.
- */
- private byte major;
- private byte minor;
-
- /**
- * Property flags.
- */
- ${pch_property_flags_declare}
-
- // Header fields from specification
-%{FLIST} ${field_declaration}
-
- /**
- * Constructor
- */
- public ${CLASS}ContentHeaderProperties(byte major, byte minor)
- {
- this.major = major;
- this.minor = minor;
-
- // Although one flag is initialized per property, the flags are used
- // in ordinal order of the AMQP version represented by this instance,
- // thus the number of flags actually used may be less than the total
- // number defined.
- ${pch_property_flags_initializer}
- }
-
- public int getPropertyListSize()
- {
- if (encodedBuffer != null)
- {
- return encodedBuffer.length;
- }
- else
- {
- int size = 0;
-%{FLIST} ${pch_field_list_size}
- return size;
- }
- }
-
- private void clearEncodedForm()
- {
- if (!decodedFlag && encodedBuffer != null)
- {
- //decode();
- }
- encodedBuffer = null;
- }
-
- public void setPropertyFlags(int[] compactPropertyFlags)
- throws AMQProtocolVersionException
- {
- clearEncodedForm();
-${pch_compact_property_flags_check}
-%{FLIST} ${pch_set_compact_property_flags}
- }
-
- public int[] getPropertyFlags()
- {
- int[] compactPropertyFlags = new int[] { 0 };
-${pch_compact_property_flags_initializer}
-%{FLIST} ${pch_get_compact_property_flags}
- return compactPropertyFlags;
- }
-
- public void writePropertyListPayload(ByteBuffer buffer)
- {
- if (encodedBuffer != null)
- {
- buffer.put(encodedBuffer);
- }
- else
- {
-%{FLIST} ${pch_field_list_payload}
- }
- }
-
- public void populatePropertiesFromBuffer(ByteBuffer buffer, int[] propertyFlags, int size)
- throws AMQFrameDecodingException, AMQProtocolVersionException
- {
- setPropertyFlags(propertyFlags);
-
- if (logger.isDebugEnabled())
- {
- logger.debug("Property flags: " + propertyFlags);
- }
- decode(buffer);
- /*encodedBuffer = new byte[size];
- buffer.get(encodedBuffer, 0, size);
- decodedFlag = false;
- decodedHeadersFlag = false;
- decodedContentTypeFlag = false;*/
- }
-
- private void decode(ByteBuffer buffer)
- {
- //ByteBuffer buffer = ByteBuffer.wrap(encodedBuffer);
- int pos = buffer.position();
- try
- {
-%{FLIST} ${pch_field_list_decode}
- // This line does nothing, but prevents a compiler error (Exception not thrown)
- // if this block is empty.
- if (false) throw new AMQFrameDecodingException("");
- }
- catch (AMQFrameDecodingException e)
- {
- throw new RuntimeException("Error in content header data: " + e);
- }
-
- final int endPos = buffer.position();
- buffer.position(pos);
- final int len = endPos - pos;
- encodedBuffer = new byte[len];
- final int limit = buffer.limit();
- buffer.limit(endPos);
- buffer.get(encodedBuffer, 0, len);
- buffer.limit(limit);
- buffer.position(endPos);
- decodedFlag = true;
- }
-
- private void decodeIfNecessary()
- {
- if (!decodedFlag)
- {
- //decode();
- }
- }
-
- // Field clear methods
-
-%{FLIST} ${pch_field_clear_methods}
-
- // Field get methods
-
-%{FLIST} ${pch_field_get_methods}
-
- // Field set methods
-
-%{FLIST} ${pch_field_set_methods}
-}
diff --git a/gentools/templ.java/method/version/MethodBodyClass.vm b/gentools/templ.java/method/version/MethodBodyClass.vm
deleted file mode 100644
index bb62438a65..0000000000
--- a/gentools/templ.java/method/version/MethodBodyClass.vm
+++ /dev/null
@@ -1,190 +0,0 @@
-#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.*;
-
-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()
- {
- int size = 0;
-#foreach( $field in $method.ConsolidatedFields )
-#if( $field.isFixedSize() )
- size += $field.Size;
-#else
- 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 String toString()
- {
- StringBuffer buf = new StringBuffer("[$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/gentools/templ.java/model/ProtocolVersionListClass.vm b/gentools/templ.java/model/ProtocolVersionListClass.vm
deleted file mode 100644
index bcf7db345b..0000000000
--- a/gentools/templ.java/model/ProtocolVersionListClass.vm
+++ /dev/null
@@ -1,154 +0,0 @@
-#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;
- private final String _stringFormat;
-
-
- public ProtocolVersion(byte majorVersion, byte minorVersion)
- {
- _majorVersion = majorVersion;
- _minorVersion = minorVersion;
- _stringFormat = _majorVersion+"-"+_minorVersion;
- }
-
- public byte getMajorVersion()
- {
- return _majorVersion;
- }
-
- public byte getMinorVersion()
- {
- return _minorVersion;
- }
-
- public String toString()
- {
- return _stringFormat;
- }
-
- 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;
-
- static
- {
- SortedSet<ProtocolVersion> versions = new TreeSet<ProtocolVersion>();
-
-#foreach( $version in $model.getVersionSet() )
- versions.add(new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor()));
-#end
- _supportedVersions = Collections.unmodifiableSortedSet(versions);
- }
-
-
- public static SortedSet<ProtocolVersion> getSupportedProtocolVersions()
- {
- return _supportedVersions;
- }
-
-
-
-
-
-}
diff --git a/gentools/templ.java/model/version/AmqpConstantsClass.vm b/gentools/templ.java/model/version/AmqpConstantsClass.vm
deleted file mode 100644
index 8d459f2977..0000000000
--- a/gentools/templ.java/model/version/AmqpConstantsClass.vm
+++ /dev/null
@@ -1,37 +0,0 @@
-&{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/gentools/templ.java/model/version/MethodRegistryClass.vm b/gentools/templ.java/model/version/MethodRegistryClass.vm
deleted file mode 100644
index 82287e7f8f..0000000000
--- a/gentools/templ.java/model/version/MethodRegistryClass.vm
+++ /dev/null
@@ -1,145 +0,0 @@
-#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.AMQMethodBodyInstanceFactory;
-import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.AMQMethodBody;
-import org.apache.qpid.framing.MethodRegistry;
-import org.apache.qpid.framing.ProtocolVersion;
-
-
-import org.apache.log4j.Logger;
-import org.apache.mina.common.ByteBuffer;
-
-public class MethodRegistry_$version.getMajor()_$version.getMinor() extends MethodRegistry
-{
-
- private static final Logger _log = Logger.getLogger(MethodRegistry.class);
-
-#set( $specificModel = $model.asSingleVersionModel() )
-
-
-
- private final AMQMethodBodyInstanceFactory[][] _factories = new AMQMethodBodyInstanceFactory[$specificModel.getMaximumClassId()+1][];
-
- 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.
-
- _factories[$amqpClass.getClassId()] = new AMQMethodBodyInstanceFactory[$amqpClass.getMaximumMethodId()+1];
-
-#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(_log,
- "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(_log,
- "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()"
- + " (while trying to decode class " + classId + " method " + methodId + ".");
-
- }
- else
- {
- throw new AMQFrameDecodingException(_log,
- "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()"
- + " (while trying to decode class " + classId + " method " + methodId + ".");
-
- }
- }
-
-
- if (bodyFactory == null)
- {
- throw new AMQFrameDecodingException(_log,
- "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;
- }
-
-
-}
diff --git a/gentools/xml-src/amqp-0.10.test.xml b/gentools/xml-src/amqp-0.10.test.xml
deleted file mode 100644
index 5d3d80648b..0000000000
--- a/gentools/xml-src/amqp-0.10.test.xml
+++ /dev/null
@@ -1,4241 +0,0 @@
-<?xml version = "1.0"?>
-
-<!--
- EDITORS: (PH) Pieter Hintjens <ph@imatix.com>
- (KvdR) Kim van der Riet <kim.vdriet@redhat.com>
-
- These editors have been assigned by the AMQP working group.
- Please do not edit/commit this file without consulting with
- one of the above editors.
- ========================================================
-
- TODOs
- - see TODO comments in the text
--->
-
-<!--
- Copyright Notice
- ================
- (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
- iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc.,
- TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
-
- License
- =======
- JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix
- Corporation, IONA\ufffd Technologies, Red Hat, Inc., TWIST Process Innovations, and
- 29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
- perpetual, royalty-free, nontransferable, nonexclusive license to
- (i) copy, display, and implement the Advanced Messaging Queue Protocol
- ("AMQP") Specification and (ii) the Licensed Claims that are held by
- the Authors, all for the purpose of implementing the Advanced Messaging
- Queue Protocol Specification. Your license and any rights under this
- Agreement will terminate immediately without notice from
- any Author if you bring any claim, suit, demand, or action related to
- the Advanced Messaging Queue Protocol Specification against any Author.
- Upon termination, you shall destroy all copies of the Advanced Messaging
- Queue Protocol Specification in your possession or control.
-
- As used hereunder, "Licensed Claims" means those claims of a patent or
- patent application, throughout the world, excluding design patents and
- design registrations, owned or controlled, or that can be sublicensed
- without fee and in compliance with the requirements of this
- Agreement, by an Author or its affiliates now or at any
- future time and which would necessarily be infringed by implementation
- of the Advanced Messaging Queue Protocol Specification. A claim is
- necessarily infringed hereunder only when it is not possible to avoid
- infringing it because there is no plausible non-infringing alternative
- for implementing the required portions of the Advanced Messaging Queue
- Protocol Specification. Notwithstanding the foregoing, Licensed Claims
- shall not include any claims other than as set forth above even if
- contained in the same patent as Licensed Claims; or that read solely
- on any implementations of any portion of the Advanced Messaging Queue
- Protocol Specification that are not required by the Advanced Messaging
- Queue Protocol Specification, or that, if licensed, would require a
- payment of royalties by the licensor to unaffiliated third parties.
- Moreover, Licensed Claims shall not include (i) any enabling technologies
- that may be necessary to make or use any Licensed Product but are not
- themselves expressly set forth in the Advanced Messaging Queue Protocol
- Specification (e.g., semiconductor manufacturing technology, compiler
- technology, object oriented technology, networking technology, operating
- system technology, and the like); or (ii) the implementation of other
- published standards developed elsewhere and merely referred to in the
- body of the Advanced Messaging Queue Protocol Specification, or
- (iii) any Licensed Product and any combinations thereof the purpose or
- function of which is not required for compliance with the Advanced
- Messaging Queue Protocol Specification. For purposes of this definition,
- the Advanced Messaging Queue Protocol Specification shall be deemed to
- include both architectural and interconnection requirements essential
- for interoperability and may also include supporting source code artifacts
- where such architectural, interconnection requirements and source code
- artifacts are expressly identified as being required or documentation to
- achieve compliance with the Advanced Messaging Queue Protocol Specification.
-
- As used hereunder, "Licensed Products" means only those specific portions
- of products (hardware, software or combinations thereof) that implement
- and are compliant with all relevant portions of the Advanced Messaging
- Queue Protocol Specification.
-
- The following disclaimers, which you hereby also acknowledge as to any
- use you may make of the Advanced Messaging Queue Protocol Specification:
-
- THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
- AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
- IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
- CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
- SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
- MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY
- PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
-
- THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
- INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
- USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
- PROTOCOL SPECIFICATION.
-
- The name and trademarks of the Authors may NOT be used in any manner,
- including advertising or publicity pertaining to the Advanced Messaging
- Queue Protocol Specification or its contents without specific, written
- prior permission. Title to copyright in the Advanced Messaging Queue
- Protocol Specification will at all times remain with the Authors.
-
- No other rights are granted by implication, estoppel or otherwise.
-
- Upon termination of your license or rights under this Agreement, you
- shall destroy all copies of the Advanced Messaging Queue Protocol
- Specification in your possession or control.
-
- Trademarks
- ==========
- "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
- Octagon Symbol are trademarks of JPMorgan Chase & Co.
-
- IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
-
- IONA, IONA Technologies, and the IONA logos are trademarks of IONA
- Technologies PLC and/or its subsidiaries.
-
- LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
- trademarks of Red Hat, Inc. in the US and other countries.
-
- Java, all Java-based trademarks and OpenOffice.org are trademarks of
- Sun Microsystems, Inc. in the United States, other countries, or both.
-
- Other company, product, or service names may be trademarks or service
- marks of others.
-
- Links to full AMQP specification:
- =================================
- http://www.envoytech.org/spec/amq/
- http://www.iona.com/opensource/amqp/
- http://www.redhat.com/solutions/specifications/amqp/
- http://www.twiststandards.org/tiki-index.php?page=AMQ
- http://www.imatix.com/amqp
--->
-
-<!--
- <!DOCTYPE amqp SYSTEM "amqp.dtd">
--->
-
-<!-- XML Notes
-
- We use entities to indicate repetition; attributes to indicate properties.
-
- We use the 'name' attribute as an identifier, usually within the context
- of the surrounding entities.
-
- We use spaces to seperate words in names, so that we can print names in
- their natural form depending on the context - underlines for source code,
- hyphens for written text, etc.
-
- We do not enforce any particular validation mechanism but we support all
- mechanisms. The protocol definition conforms to a formal grammar that is
- published seperately in several technologies.
-
- -->
-
-<amqp major = "0" minor = "10" port = "5672" comment = "AMQ Protocol">
- <!--
- ======================================================
- == CONSTANTS
- ======================================================
- -->
- <!-- Frame types -->
- <constant name = "frame-method" value = "1" />
- <constant name = "frame-header" value = "2" />
- <constant name = "frame-body" value = "3" />
- <constant name = "frame-oob-method" value = "4" />
- <constant name = "frame-oob-header" value = "5" />
- <constant name = "frame-oob-body" value = "6" />
- <constant name = "frame-trace" value = "7" />
- <constant name = "frame-heartbeat" value = "8" />
-
- <!-- Protocol constants -->
- <constant name = "frame-min-size" value = "4096" />
- <constant name = "frame-end" value = "206" />
-
- <!-- Reply codes -->
- <constant name = "reply-success" value = "200">
- <doc>
- Indicates that the method completed successfully. This reply code is
- reserved for future use - the current protocol design does not use positive
- confirmation and reply codes are sent only in case of an error.
- </doc>
- </constant>
-
- <constant name = "not-delivered" value = "310" class = "soft-error">
- <doc>
- The client asked for a specific message that is no longer available.
- The message was delivered to another client, or was purged from the queue
- for some other reason.
- </doc>
- </constant>
-
- <constant name = "content-too-large" value = "311" class = "soft-error">
- <doc>
- The client attempted to transfer content larger than the server could accept
- at the present time. The client may retry at a later time.
- </doc>
- </constant>
-
- <constant name = "connection-forced" value = "320" class = "hard-error">
- <doc>
- An operator intervened to close the connection for some reason. The client
- may retry at some later date.
- </doc>
- </constant>
-
- <constant name = "invalid-path" value = "402" class = "hard-error">
- <doc>
- The client tried to work with an unknown virtual host.
- </doc>
- </constant>
-
- <constant name = "access-refused" value = "403" class = "soft-error">
- <doc>
- The client attempted to work with a server entity to which it has no
- access due to security settings.
- </doc>
- </constant>
-
- <constant name = "not-found" value = "404" class = "soft-error">
- <doc>The client attempted to work with a server entity that does not exist.</doc>
- </constant>
-
- <constant name = "resource-locked" value = "405" class = "soft-error">
- <doc>
- The client attempted to work with a server entity to which it has no
- access because another client is working with it.
- </doc>
- </constant>
-
- <constant name = "precondition-failed" value = "406" class = "soft-error">
- <doc>
- The client requested a method that was not allowed because some precondition
- failed.
- </doc>
- </constant>
-
- <constant name = "frame-error" value = "501" class = "hard-error">
- <doc>
- The client sent a malformed frame that the server could not decode. This
- strongly implies a programming error in the client.
- </doc>
- </constant>
-
- <constant name = "syntax-error" value = "502" class = "hard-error">
- <doc>
- The client sent a frame that contained illegal values for one or more
- fields. This strongly implies a programming error in the client.
- </doc>
- </constant>
-
- <constant name = "command-invalid" value = "503" class = "hard-error">
- <doc>
- The client sent an invalid sequence of frames, attempting to perform an
- operation that was considered invalid by the server. This usually implies
- a programming error in the client.
- </doc>
- </constant>
-
- <constant name = "channel-error" value = "504" class = "hard-error">
- <doc>
- The client attempted to work with a channel that had not been correctly
- opened. This most likely indicates a fault in the client layer.
- </doc>
- </constant>
-
- <constant name = "resource-error" value = "506" class = "hard-error">
- <doc>
- The server could not complete the method because it lacked sufficient
- resources. This may be due to the client creating too many of some type
- of entity.
- </doc>
- </constant>
-
- <constant name = "not-allowed" value = "530" class = "hard-error">
- <doc>
- The client tried to work with some entity in a manner that is prohibited
- by the server, due to security settings or by some other criteria.
- </doc>
- </constant>
-
- <constant name = "not-implemented" value = "540" class = "hard-error">
- <doc>
- The client tried to use functionality that is not implemented in the
- server.
- </doc>
- </constant>
-
- <constant name = "internal-error" value = "545" class = "hard-error">
- <doc>
- The server could not complete the method because of an internal error.
- The server may require intervention by an operator in order to resume
- normal operations.
- </doc>
- </constant>
-
- <constant name = "test-double" value = "3.141592654"/>
- <constant name = "test-str1" value = "hello, world!"/>
- <constant name = "test-str2" value = "1.2.3.4"/>
-
- <!--
- ======================================================
- == DOMAIN TYPES
- ======================================================
- -->
-
- <domain name = "access-ticket" type = "short" label = "access ticket granted by server">
- <doc>
- An access ticket granted by the server for a certain set of access rights
- within a specific realm. Access tickets are valid within the channel where
- they were created, and expire when the channel closes.
- </doc>
- <assert check = "ne" value = "0" />
- </domain>
-
- <domain name = "class-id" type = "short" />
-
- <domain name = "consumer-tag" type = "shortstr" label = "consumer tag">
- <doc>
- Identifier for the consumer, valid within the current connection.
- </doc>
- </domain>
-
- <domain name = "delivery-tag" type = "longlong" label = "server-assigned delivery tag">
- <doc>
- The server-assigned and channel-specific delivery tag
- </doc>
- <rule name = "channel-local">
- <doc>
- The delivery tag is valid only within the channel from which the message was
- received. I.e. a client MUST NOT receive a message on one channel and then
- acknowledge it on another.
- </doc>
- </rule>
- <rule name = "non-zero">
- <doc>
- The server MUST NOT use a zero value for delivery tags. Zero is reserved
- for client use, meaning "all messages so far received".
- </doc>
- </rule>
- </domain>
-
- <domain name = "exchange-name" type = "shortstr" label = "exchange name">
- <doc>
- The exchange name is a client-selected string that identifies the exchange for publish
- methods. Exchange names may consist of any mixture of digits, letters, and underscores.
- Exchange names are scoped by the virtual host.
- </doc>
- <assert check = "length" value = "127" />
- </domain>
-
- <domain name = "known-hosts" type = "shortstr" label = "list of known hosts">
- <doc>
- Specifies the list of equivalent or alternative hosts that the server knows about,
- which will normally include the current server itself. Clients can cache this
- information and use it when reconnecting to a server after a failure. This field
- may be empty.
- </doc>
- </domain>
-
- <domain name = "method-id" type = "long" />
-
- <domain name = "no-ack" type = "bit" label = "no acknowledgement needed">
- <doc>
- If this field is set the server does not expect acknowledgments for
- messages. That is, when a message is delivered to the client the server
- automatically and silently acknowledges it on behalf of the client. This
- functionality increases performance but at the cost of reliability.
- Messages can get lost if a client dies before it can deliver them to the
- application.
- </doc>
- </domain>
-
- <domain name = "no-local" type = "bit" label = "do not deliver own messages">
- <doc>
- If the no-local field is set the server will not send messages to the client that
- published them.
- </doc>
- </domain>
-
- <domain name = "path" type = "shortstr">
- <doc>
- Must start with a slash "/" and continue with path names separated by slashes. A path
- name consists of any combination of at least one of [A-Za-z0-9] plus zero or more of
- [.-_+!=:].
- </doc>
-
- <assert check = "notnull" />
- <assert check = "syntax" rule = "path" />
- <assert check = "length" value = "127" />
- </domain>
-
- <domain name = "peer-properties" type = "table">
- <doc>
- This string provides a set of peer properties, used for identification, debugging, and
- general information.
- </doc>
- </domain>
-
- <domain name = "queue-name" type = "shortstr" label = "queue name">
- <doc>
- The queue name identifies the queue within the vhost. Queue names may consist of any
- mixture of digits, letters, and underscores.
- </doc>
- <assert check = "length" value = "127" />
- </domain>
-
- <domain name = "redelivered" type = "bit" label = "message is being redelivered">
- <doc>
- This indicates that the message has been previously delivered to this or
- another client.
- </doc>
- <rule name = "implementation">
- <doc>
- The server SHOULD try to signal redelivered messages when it can. When
- redelivering a message that was not successfully acknowledged, the server
- SHOULD deliver it to the original client if possible.
- </doc>
- <doc type = "scenario">
- Create a shared queue and publish a message to the queue. Consume the
- message using explicit acknowledgements, but do not acknowledge the
- message. Close the connection, reconnect, and consume from the queue
- again. The message should arrive with the redelivered flag set.
- </doc>
- </rule>
- <rule name = "hinting">
- <doc>
- The client MUST NOT rely on the redelivered field but should take it as a
- hint that the message may already have been processed. A fully robust
- client must be able to track duplicate received messages on non-transacted,
- and locally-transacted channels.
- </doc>
- </rule>
- </domain>
-
- <domain name = "reply-code" type = "short" label = "reply code from server">
- <doc>
- The reply code. The AMQ reply codes are defined as constants at the start
- of this formal specification.
- </doc>
- <assert check = "notnull" />
- </domain>
-
- <domain name = "reply-text" type = "shortstr" label = "localised reply text">
- <doc>
- The localised reply text. This text can be logged as an aid to resolving
- issues.
- </doc>
- <assert check = "notnull" />
- </domain>
-
- <!-- Elementary domains -->
- <domain name = "bit" type = "bit" label = "single bit" />
- <domain name = "octet" type = "octet" label = "single octet" />
- <domain name = "short" type = "short" label = "16-bit integer" />
- <domain name = "long" type = "long" label = "32-bit integer" />
- <domain name = "longlong" type = "longlong" label = "64-bit integer" />
- <domain name = "shortstr" type = "shortstr" label = "short string" />
- <domain name = "longstr" type = "longstr" label = "long string" />
- <domain name = "timestamp" type = "timestamp" label = "64-bit timestamp" />
- <domain name = "table" type = "table" label = "field table" />
-
- <!-- == CONNECTION ======================================================= -->
-
- <!-- TODO 0.81 - the 'handler' attribute of methods needs to be reviewed, and if
- no current implementations use it, removed. /PH 2006/07/20
- -->
-
- <class name = "connection" handler = "connection" index = "10" label = "work with socket connections">
- <doc>
- The connection class provides methods for a client to establish a network connection to
- a server, and for both peers to operate the connection thereafter.
- </doc>
-
- <doc type = "grammar">
- connection = open-connection *use-connection close-connection
- open-connection = C:protocol-header
- S:START C:START-OK
- *challenge
- S:TUNE C:TUNE-OK
- C:OPEN S:OPEN-OK | S:REDIRECT
- challenge = S:SECURE C:SECURE-OK
- use-connection = *channel
- close-connection = C:CLOSE S:CLOSE-OK
- / S:CLOSE C:CLOSE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "start" synchronous = "1" index = "10" label = "start connection negotiation">
- <doc>
- This method starts the connection negotiation process by telling the client the
- protocol version that the server proposes, along with a list of security mechanisms
- which the client can use for authentication.
- </doc>
-
- <rule name = "protocol-name">
- <doc>
- If the server cannot support the protocol specified in the protocol header,
- it MUST close the socket connection without sending any response method.
- </doc>
- <doc type = "scenario">
- The client sends a protocol header containing an invalid protocol name.
- The server must respond by closing the connection.
- </doc>
- </rule>
- <rule name = "server-support">
- <doc>
- The server MUST provide a protocol version that is lower than or equal to
- that requested by the client in the protocol header.
- </doc>
- <doc type = "scenario">
- The client requests a protocol version that is higher than any valid
- implementation, e.g. 9.0. The server must respond with a current
- protocol version, e.g. 1.0.
- </doc>
- </rule>
- <rule name = "client-support">
- <doc>
- If the client cannot handle the protocol version suggested by the server
- it MUST close the socket connection.
- </doc>
- <doc type = "scenario">
- The server sends a protocol version that is lower than any valid
- implementation, e.g. 0.1. The client must respond by closing the
- connection.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
- <response name = "start-ok" />
-
- <field name = "version-major" domain = "octet" label = "protocol major version">
- <doc>
- The version of the protocol, expressed in protocol units of 0.1 public
- versions and properly printed as two digits with a leading zero. I.e. a
- protocol version of "09" represents a public version "0.9". The decimal
- shift allows the correct expression of pre-1.0 protocol releases.
- </doc>
- <doc type = "todo">
- This field should be renamed to "protocol version".
- </doc>
- </field>
-
- <field name = "version-minor" domain = "octet" label = "protocol major version">
- <doc>
- The protocol revision, expressed as an integer from 0 to 9. The use of more
- than ten revisions is discouraged. The public version string is constructed
- from the protocol version and revision as follows: we print the protocol
- version with one decimal position, and we append the protocol revision. A
- version=10 and revision=2 are printed as "1.02".
- </doc>
- <doc type = "todo">
- This field should be renamed to "protocol revision".
- </doc>
- </field>
-
- <field name = "server-properties" domain = "peer-properties" label = "server properties">
- <rule name = "required-fields">
- <doc>
- The properties SHOULD contain at least these fields: "host", specifying the
- server host name or address, "product", giving the name of the server product,
- "version", giving the name of the server version, "platform", giving the name
- of the operating system, "copyright", if appropriate, and "information", giving
- other general information.
- </doc>
- <doc type = "scenario">
- Client connects to server and inspects the server properties. It checks for
- the presence of the required fields.
- </doc>
- </rule>
- </field>
-
- <field name = "mechanisms" domain = "longstr" label = "available security mechanisms">
- <doc>
- A list of the security mechanisms that the server supports, delimited by spaces.
- Currently ASL supports these mechanisms: PLAIN.
- </doc>
- <assert check = "notnull" />
- </field>
-
- <field name = "locales" domain = "longstr" label = "available message locales">
- <doc>
- A list of the message locales that the server supports, delimited by spaces. The
- locale defines the language in which the server will send reply texts.
- </doc>
- <rule name = "required-support">
- <doc>
- The server MUST support at least the en_US locale.
- </doc>
- <doc type = "scenario">
- Client connects to server and inspects the locales field. It checks for
- the presence of the required locale(s).
- </doc>
- </rule>
- <assert check = "notnull" />
- </field>
- </method>
-
- <method name = "start-ok" synchronous = "1" index = "11"
- label = "select security mechanism and locale">
- <doc>
- This method selects a SASL security mechanism. ASL uses SASL (RFC2222) to
- negotiate authentication and encryption.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "client-properties" domain = "peer-properties" label = "client properties">
- <rule name = "required-fields">
- <!-- This rule is not testable from the client side -->
- <doc>
- The properties SHOULD contain at least these fields: "product", giving the name
- of the client product, "version", giving the name of the client version, "platform",
- giving the name of the operating system, "copyright", if appropriate, and
- "information", giving other general information.
- </doc>
- </rule>
- </field>
-
- <field name = "mechanism" domain = "shortstr" label = "selected security mechanism">
- <doc>
- A single security mechanisms selected by the client, which must be one of those
- specified by the server.
- </doc>
- <rule name = "security">
- <doc>
- The client SHOULD authenticate using the highest-level security profile it
- can handle from the list provided by the server.
- </doc>
- </rule>
- <rule name = "validity">
- <doc>
- If the mechanism field does not contain one of the security mechanisms
- proposed by the server in the Start method, the server MUST close the
- connection without sending any further data.
- </doc>
- <doc type = "scenario">
- Client connects to server and sends an invalid security mechanism. The
- server must respond by closing the connection (a socket close, with no
- connection close negotiation).
- </doc>
- </rule>
- <assert check = "notnull" />
- </field>
-
- <field name = "response" domain = "longstr" label = "security response data">
- <doc>
- A block of opaque data passed to the security mechanism. The contents of this
- data are defined by the SASL security mechanism.
- </doc>
- <assert check = "notnull" />
- </field>
-
- <field name = "locale" domain = "shortstr" label = "selected message locale">
- <doc>
- A single message local selected by the client, which must be one of those
- specified by the server.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "secure" synchronous = "1" index = "20" label = "security mechanism challenge">
- <doc>
- The SASL protocol works by exchanging challenges and responses until both peers have
- received sufficient information to authenticate each other. This method challenges
- the client to provide more information.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
- <response name = "secure-ok" />
-
- <field name = "challenge" domain = "longstr" label = "security challenge data">
- <doc>
- Challenge information, a block of opaque binary data passed to the security
- mechanism.
- </doc>
- </field>
- </method>
-
- <method name = "secure-ok" synchronous = "1" index = "21" label = "security mechanism response">
- <doc>
- This method attempts to authenticate, passing a block of SASL data for the security
- mechanism at the server side.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "response" domain = "longstr" label = "security response data">
- <doc>
- A block of opaque data passed to the security mechanism. The contents of this
- data are defined by the SASL security mechanism.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "tune" synchronous = "1" index = "30"
- label = "propose connection tuning parameters">
- <doc>
- This method proposes a set of connection configuration values to the client. The
- client can accept and/or adjust these.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <response name = "tune-ok" />
-
- <field name = "channel-max" domain = "short" label = "proposed maximum channels">
- <doc>
- The maximum total number of channels that the server allows per connection. Zero
- means that the server does not impose a fixed limit, but the number of allowed
- channels may be limited by available server resources.
- </doc>
- </field>
-
- <field name = "frame-max" domain = "long" label = "proposed maximum frame size">
- <doc>
- The largest frame size that the server proposes for the connection. The client
- can negotiate a lower value. Zero means that the server does not impose any
- specific limit but may reject very large frames if it cannot allocate resources
- for them.
- </doc>
- <rule name = "minimum">
- <doc>
- Until the frame-max has been negotiated, both peers MUST accept frames of up
- to frame-min-size octets large, and the minimum negotiated value for frame-max
- is also frame-min-size.
- </doc>
- <doc type = "scenario">
- Client connects to server and sends a large properties field, creating a frame
- of frame-min-size octets. The server must accept this frame.
- </doc>
- </rule>
- </field>
-
- <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
- <!-- TODO 0.82 - the heartbeat negotiation mechanism was changed during
- implementation because the model documented here does not actually
- work properly. The best model we found is that the server proposes
- a heartbeat value to the client; the client can reply with zero, meaning
- 'do not use heartbeats (as documented here), or can propose its own
- heartbeat value, which the server should then accept. This is different
- from the model here which is disconnected - e.g. each side requests a
- heartbeat independently. Basically a connection is heartbeated in
- both ways, or not at all, depending on whether both peers support
- heartbeating or not, and the heartbeat value should itself be chosen
- by the client so that remote links can get a higher value. Also, the
- actual heartbeat mechanism needs documentation, and is as follows: so
- long as there is activity on a connection - in or out - both peers
- assume the connection is active. When there is no activity, each peer
- must send heartbeat frames. When no heartbeat frame is received after
- N cycles (where N is at least 2), the connection can be considered to
- have died. /PH 2006/07/19
- -->
- <doc>
- The delay, in seconds, of the connection heartbeat that the server wants.
- Zero means the server does not want a heartbeat.
- </doc>
- </field>
- </method>
-
- <method name = "tune-ok" synchronous = "1" index = "31"
- label = "negotiate connection tuning parameters">
- <doc>
- This method sends the client's connection tuning parameters to the server.
- Certain fields are negotiated, others provide capability information.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "channel-max" domain = "short" label = "negotiated maximum channels">
- <doc>
- The maximum total number of channels that the client will use per connection.
- </doc>
- <rule name = "upper-limit">
- <doc>
- If the client specifies a channel max that is higher than the value provided
- by the server, the server MUST close the connection without attempting a
- negotiated close. The server may report the error in some fashion to assist
- implementors.
- </doc>
- </rule>
- <assert check = "notnull" />
- <assert check = "le" method = "tune" field = "channel-max" />
- </field>
-
- <field name = "frame-max" domain = "long" label = "negotiated maximum frame size">
- <doc>
- The largest frame size that the client and server will use for the connection.
- Zero means that the client does not impose any specific limit but may reject
- very large frames if it cannot allocate resources for them. Note that the
- frame-max limit applies principally to content frames, where large contents can
- be broken into frames of arbitrary size.
- </doc>
- <rule name = "minimum">
- <doc>
- Until the frame-max has been negotiated, both peers MUST accept frames of up
- to frame-min-size octets large, and the minimum negotiated value for frame-max
- is also frame-min-size.
- </doc>
- </rule>
- <rule name = "upper-limit">
- <doc>
- If the client specifies a frame max that is higher than the value provided
- by the server, the server MUST close the connection without attempting a
- negotiated close. The server may report the error in some fashion to assist
- implementors.
- </doc>
- </rule>
- </field>
-
- <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
- <doc>
- The delay, in seconds, of the connection heartbeat that the client wants. Zero
- means the client does not want a heartbeat.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "open" synchronous = "1" index = "40" label = "open connection to virtual host">
- <doc>
- This method opens a connection to a virtual host, which is a collection of
- resources, and acts to separate multiple application domains within a server.
- The server may apply arbitrary limits per virtual host, such as the number
- of each type of entity that may be used, per connection and/or in total.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "open-ok" />
- <response name = "redirect" />
-
- <field name = "virtual-host" domain = "path" label = "virtual host name">
- <!-- TODO 0.82 - the entire vhost model needs review. This concept was
- prompted by the HTTP vhost concept but does not fit very well into
- AMQP. Currently we use the vhost as a "cluster identifier" which is
- inaccurate usage. /PH 2006/07/19
- -->
- <assert check = "regexp" value = "^[a-zA-Z0-9/-_]+$" />
- <doc>
- The name of the virtual host to work with.
- </doc>
- <rule name = "separation">
- <doc>
- If the server supports multiple virtual hosts, it MUST enforce a full
- separation of exchanges, queues, and all associated entities per virtual
- host. An application, connected to a specific virtual host, MUST NOT be able
- to access resources of another virtual host.
- </doc>
- </rule>
- <rule name = "security">
- <doc>
- The server SHOULD verify that the client has permission to access the
- specified virtual host.
- </doc>
- </rule>
- </field>
-
- <field name = "capabilities" domain = "shortstr" label = "required capabilities">
- <doc>
- The client can specify zero or more capability names, delimited by spaces.
- The server can use this string to how to process the client's connection
- request.
- </doc>
- </field>
-
- <field name = "insist" domain = "bit" label = "insist on connecting to server">
- <doc>
- In a configuration with multiple collaborating servers, the server may respond
- to a Connection.Open method with a Connection.Redirect. The insist option tells
- the server that the client is insisting on a connection to the specified server.
- </doc>
- <rule name = "behaviour">
- <doc>
- When the client uses the insist option, the server MUST NOT respond with a
- Connection.Redirect method. If it cannot accept the client's connection
- request it should respond by closing the connection with a suitable reply
- code.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "open-ok" synchronous = "1" index = "41" label = "signal that connection is ready">
- <doc>
- This method signals to the client that the connection is ready for use.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "known-hosts" domain = "known-hosts" />
- </method>
-
- <method name = "redirect" synchronous = "1" index = "42" label = "redirects client to other server">
- <doc>
- This method redirects the client to another server, based on the requested virtual
- host and/or capabilities.
- </doc>
- <rule name = "usage">
- <doc>
- When getting the Connection.Redirect method, the client SHOULD reconnect to
- the host specified, and if that host is not present, to any of the hosts
- specified in the known-hosts list.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <field name = "host" domain = "shortstr" label = "server to connect to">
- <doc>
- Specifies the server to connect to. This is an IP address or a DNS name,
- optionally followed by a colon and a port number. If no port number is
- specified, the client should use the default port number for the protocol.
- </doc>
- <assert check = "notnull" />
- </field>
- <field name = "known-hosts" domain = "known-hosts" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "close" synchronous = "1" index = "50" label = "request a connection close">
- <doc>
- This method indicates that the sender wants to close the connection. This may be
- due to internal conditions (e.g. a forced shut-down) or due to an error handling
- a specific method, i.e. an exception. When a close is due to an exception, the
- sender provides the class and method id of the method which caused the exception.
- </doc>
- <!-- TODO: the connection close mechanism needs to be reviewed from the ODF
- documentation and better expressed as rules here. /PH 2006/07/20
- -->
- <rule name = "stability">
- <doc>
- After sending this method any received method except the Close-OK method MUST
- be discarded.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- <response name = "close-ok" />
-
- <field name = "reply-code" domain = "reply-code" />
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "class-id" domain = "class-id" label = "failing method class">
- <doc>
- When the close is provoked by a method exception, this is the class of the
- method.
- </doc>
- </field>
-
- <field name = "method-id" domain = "method-id" label = "failing method ID">
- <doc>
- When the close is provoked by a method exception, this is the ID of the method.
- </doc>
- </field>
- </method>
-
- <method name = "close-ok" synchronous = "1" index = "51" label = "confirm a connection close">
- <doc>
- This method confirms a Connection.Close method and tells the recipient that it is
- safe to release resources for the connection and close the socket.
- </doc>
- <rule name = "reporting">
- <doc>
- A peer that detects a socket closure without having received a Close-Ok
- handshake method SHOULD log the error.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- </method>
- </class>
-
- <!-- == CHANNEL ========================================================== -->
-
- <class name = "channel" handler = "channel" index = "20" label = "work with channels">
- <doc>
- The channel class provides methods for a client to establish a channel to a
- server and for both peers to operate the channel thereafter.
- </doc>
-
- <doc type = "grammar">
- channel = open-channel *use-channel close-channel
- open-channel = C:OPEN S:OPEN-OK
- use-channel = C:FLOW S:FLOW-OK
- / S:FLOW C:FLOW-OK
- / S:ALERT
- / functional-class
- close-channel = C:CLOSE S:CLOSE-OK
- / S:CLOSE C:CLOSE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "open" synchronous = "1" index = "10" label = "open a channel for use">
- <doc>
- This method opens a channel to the server.
- </doc>
- <rule name = "state" on-failure = "channel-error">
- <doc>
- The client MUST NOT use this method on an alread-opened channel.
- </doc>
- <doc type = "scenario">
- Client opens a channel and then reopens the same channel.
- </doc>
- </rule>
- <chassis name = "server" implement = "MUST" />
- <response name = "open-ok" />
- <field name = "out of band" domain = "shortstr" label = "out-of-band settings">
- <doc>
- Configures out-of-band transfers on this channel. The syntax and meaning of this
- field will be formally defined at a later date.
- </doc>
- <assert check = "null" />
- </field>
- </method>
-
- <method name = "open-ok" synchronous = "1" index = "11" label = "signal that the channel is ready">
- <doc>
- This method signals to the client that the channel is ready for use.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "flow" synchronous = "1" index = "20" label = "enable/disable flow from peer">
- <doc>
- This method asks the peer to pause or restart the flow of content data. This is a
- simple flow-control mechanism that a peer can use to avoid oveflowing its queues or
- otherwise finding itself receiving more messages than it can process. Note that this
- method is not intended for window control. The peer that receives a disable flow
- method should finish sending the current content frame, if any, then pause.
- </doc>
-
- <rule name = "initial-state">
- <doc>
- When a new channel is opened, it is active (flow is active). Some applications
- assume that channels are inactive until started. To emulate this behaviour a
- client MAY open the channel, then pause it.
- </doc>
- </rule>
-
- <rule name = "bidirectional">
- <doc>
- When sending content frames, a peer SHOULD monitor the channel for incoming
- methods and respond to a Channel.Flow as rapidly as possible.
- </doc>
- </rule>
-
- <rule name = "throttling">
- <doc>
- A peer MAY use the Channel.Flow method to throttle incoming content data for
- internal reasons, for example, when exchanging data over a slower connection.
- </doc>
- </rule>
-
- <rule name = "expected-behaviour">
- <doc>
- The peer that requests a Channel.Flow method MAY disconnect and/or ban a peer
- that does not respect the request. This is to prevent badly-behaved clients
- from overwhelming a broker.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <response name = "flow-ok" />
-
- <field name = "active" domain = "bit" label = "start/stop content frames">
- <doc>
- If 1, the peer starts sending content frames. If 0, the peer stops sending
- content frames.
- </doc>
- </field>
- </method>
-
- <method name = "flow-ok" index = "21" label = "confirm a flow method">
- <doc>
- Confirms to the peer that a flow command was received and processed.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
- <field name = "active" domain = "bit" label = "current flow setting">
- <doc>
- Confirms the setting of the processed flow method: 1 means the peer will start
- sending or continue to send content frames; 0 means it will not.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- TODO 0.82 - remove this method entirely
- /PH 2006/07/20
- -->
- <method name = "alert" index = "30" label = "send a non-fatal warning message">
- <doc>
- This method allows the server to send a non-fatal warning to the client. This is
- used for methods that are normally asynchronous and thus do not have confirmations,
- and for which the server may detect errors that need to be reported. Fatal errors
- are handled as channel or connection exceptions; non-fatal errors are sent through
- this method.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "reply-code" domain = "reply-code" />
- <field name = "reply-text" domain = "reply-text" />
- <field name = "details" domain = "table" label = "detailed information for warning">
- <doc>
- A set of fields that provide more information about the problem. The meaning of
- these fields are defined on a per-reply-code basis (TO BE DEFINED).
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "close" synchronous = "1" index = "40" label = "request a channel close">
- <doc>
- This method indicates that the sender wants to close the channel. This may be due to
- internal conditions (e.g. a forced shut-down) or due to an error handling a specific
- method, i.e. an exception. When a close is due to an exception, the sender provides
- the class and method id of the method which caused the exception.
- </doc>
-
- <!-- TODO: the channel close behaviour needs to be reviewed from the ODF
- documentation and better expressed as rules here. /PH 2006/07/20
- -->
- <rule name = "stability">
- <doc>
- After sending this method any received method except the Close-OK method MUST
- be discarded.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- <response name = "close-ok" />
-
- <field name = "reply-code" domain = "reply-code" />
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "class-id" domain = "class-id" label = "failing method class">
- <doc>
- When the close is provoked by a method exception, this is the class of the
- method.
- </doc>
- </field>
-
- <field name = "method-id" domain = "method-id" label = "failing method ID">
- <doc>
- When the close is provoked by a method exception, this is the ID of the method.
- </doc>
- </field>
- </method>
-
- <method name = "close-ok" synchronous = "1" index = "41" label = "confirm a channel close">
- <doc>
- This method confirms a Channel.Close method and tells the recipient that it is safe
- to release resources for the channel and close the socket.
- </doc>
- <rule name = "reporting">
- <doc>
- A peer that detects a socket closure without having received a Channel.Close-Ok
- handshake method SHOULD log the error.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- </method>
- </class>
-
- <!-- == ACCESS =========================================================== -->
-
- <!-- TODO 0.82 - this class must be implemented by two teams before we can
- consider it matured.
- -->
-
- <class name = "access" handler = "connection" index = "30" label = "work with access tickets">
- <doc>
- The protocol control access to server resources using access tickets. A
- client must explicitly request access tickets before doing work. An access
- ticket grants a client the right to use a specific set of resources -
- called a "realm" - in specific ways.
- </doc>
-
- <doc type = "grammar">
- access = C:REQUEST S:REQUEST-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "request" synchronous = "1" index = "10" label = "request an access ticket">
- <doc>
- This method requests an access ticket for an access realm. The server
- responds by granting the access ticket. If the client does not have
- access rights to the requested realm this causes a connection exception.
- Access tickets are a per-channel resource.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "request-ok" />
-
- <field name = "realm" domain = "shortstr" label = "name of requested realm">
- <doc>
- Specifies the name of the realm to which the client is requesting access.
- The realm is a configured server-side object that collects a set of
- resources (exchanges, queues, etc.). If the channel has already requested
- an access ticket onto this realm, the previous ticket is destroyed and a
- new ticket is created with the requested access rights, if allowed.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST specify a realm that is known to the server. The server
- makes an identical response for undefined realms as it does for realms
- that are defined but inaccessible to this client.
- </doc>
- <doc type = "scenario">
- Client specifies an undefined realm.
- </doc>
- </rule>
- </field>
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive access to the realm, meaning that this will be the only
- channel that uses the realm's resources.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MAY NOT request exclusive access to a realm that has active
- access tickets, unless the same channel already had the only access
- ticket onto that realm.
- </doc>
- <doc type = "scenario">
- Client opens two channels and requests exclusive access to the same realm.
- </doc>
- </rule>
- </field>
- <field name = "passive" domain = "bit" label = "request passive access">
- <doc>
- Request message passive access to the specified access realm. Passive
- access lets a client get information about resources in the realm but
- not to make any changes to them.
- </doc>
- </field>
- <field name = "active" domain = "bit" label = "request active access">
- <doc>
- Request message active access to the specified access realm. Active access lets
- a client get create and delete resources in the realm.
- </doc>
- </field>
- <field name = "write" domain = "bit" label = "request write access">
- <doc>
- Request write access to the specified access realm. Write access lets a client
- publish messages to all exchanges in the realm.
- </doc>
- </field>
- <field name = "read" domain = "bit" label = "request read access">
- <doc>
- Request read access to the specified access realm. Read access lets a client
- consume messages from queues in the realm.
- </doc>
- </field>
- </method>
-
- <method name = "request-ok" synchronous = "1" index = "11" label = "grant access to server resources">
- <doc>
- This method provides the client with an access ticket. The access ticket is valid
- within the current channel and for the lifespan of the channel.
- </doc>
- <rule name = "per-channel" on-failure = "not-allowed">
- <doc>
- The client MUST NOT use access tickets except within the same channel as
- originally granted.
- </doc>
- <doc type = "scenario">
- Client opens two channels, requests a ticket on one channel, and then
- tries to use that ticket in a seconc channel.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <field name = "ticket" domain = "access-ticket" />
- </method>
- </class>
-
- <!-- == EXCHANGE ========================================================= -->
-
- <class name = "exchange" handler = "channel" index = "40" label = "work with exchanges">
- <doc>
- Exchanges match and distribute messages across queues. Exchanges can be configured in
- the server or created at runtime.
- </doc>
-
- <doc type = "grammar">
- exchange = C:DECLARE S:DECLARE-OK
- / C:DELETE S:DELETE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <rule name = "required-types">
- <doc>
- The server MUST implement these standard exchange types: fanout, direct.
- </doc>
- <doc type = "scenario">
- Client attempts to declare an exchange with each of these standard types.
- </doc>
- </rule>
- <rule name = "recommended-types">
- <doc>
- The server SHOULD implement these standard exchange types: topic, headers.
- </doc>
- <doc type = "scenario">
- Client attempts to declare an exchange with each of these standard types.
- </doc>
- </rule>
- <rule name = "required-instances">
- <doc>
- The server MUST, in each virtual host, pre-declare an exchange instance
- for each standard exchange type that it implements, where the name of the
- exchange instance is "amq." followed by the exchange type name.
- </doc>
- <doc type = "scenario">
- Client creates a temporary queue and attempts to bind to each required
- exchange instance (amq.fanout, amq.direct, and amq.topic, amq.headers if
- those types are defined).
- </doc>
- </rule>
- <rule name = "default-exchange">
- <doc>
- The server MUST predeclare a direct exchange to act as the default exchange
- for content Publish methods and for default queue bindings.
- </doc>
- <doc type = "scenario">
- Client checks that the default exchange is active by specifying a queue
- binding with no exchange name, and publishing a message with a suitable
- routing key but without specifying the exchange name, then ensuring that
- the message arrives in the queue correctly.
- </doc>
- </rule>
- <rule name = "default-access">
- <doc>
- The server MUST NOT allow clients to access the default exchange except
- by specifying an empty exchange name in the Queue.Bind and content Publish
- methods.
- </doc>
- </rule>
- <rule name = "extensions">
- <doc>
- The server MAY implement other exchange types as wanted.
- </doc>
- </rule>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "declare" synchronous = "1" index = "10" label = "declare exchange, create if needed">
- <doc>
- This method creates an exchange if it does not already exist, and if the exchange
- exists, verifies that it is of the correct and expected class.
- </doc>
- <rule name = "minimum">
- <doc>
- The server SHOULD support a minimum of 16 exchanges per virtual host and
- ideally, impose no limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- The client creates as many exchanges as it can until the server reports
- an error; the number of exchanges successfuly created must be at least
- sixteen.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "declare-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- When a client defines a new exchange, this belongs to the access realm of the
- ticket used. All further work done with that exchange must be done with an
- access ticket for the same realm.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "active" access to
- the realm in which the exchange exists or will be created, or "passive"
- access if the if-exists flag is set.
- </doc>
- <doc type = "scenario">
- Client creates access ticket with wrong access rights and attempts to use
- in this method.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <rule name = "reserved" on-failure = "access-refused">
- <doc>
- Exchange names starting with "amq." are reserved for predeclared and
- standardised exchanges. The client MUST NOT attempt to create an exchange
- starting with "amq.".
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" />
- </field>
-
- <field name = "type" domain = "shortstr" label = "exchange type">
- <doc>
- Each exchange belongs to one of a set of exchange types implemented by the
- server. The exchange types define the functionality of the exchange - i.e. how
- messages are routed through it. It is not valid or meaningful to attempt to
- change the type of an existing exchange.
- </doc>
- <rule name = "typed" on-failure = "not-allowed">
- <doc>
- Exchanges cannot be redeclared with different types. The client MUST not
- attempt to redeclare an existing exchange with a different type than used
- in the original Exchange.Declare method.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <rule name = "support" on-failure = "command-invalid">
- <doc>
- The client MUST NOT attempt to create an exchange with a type that the
- server does not support.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" />
- </field>
-
- <field name = "passive" domain = "bit" label = "do not create exchange">
- <doc>
- If set, the server will not create the exchange. The client can use this to
- check whether an exchange exists without modifying the server state.
- </doc>
- <rule name = "not-found">
- <doc>
- If set, and the exchange does not already exist, the server MUST raise a
- channel exception with reply code 404 (not found).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "durable" domain = "bit" label = "request a durable exchange">
- <doc>
- If set when creating a new exchange, the exchange will be marked as durable.
- Durable exchanges remain active when a server restarts. Non-durable exchanges
- (transient exchanges) are purged if/when a server restarts.
- </doc>
- <rule name = "support">
- <doc>
- The server MUST support both durable and transient exchanges.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <rule name = "sticky">
- <doc>
- The server MUST ignore the durable field if the exchange already exists.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <!-- TODO 0.82 - clarify how this works; there is no way to cancel a binding
- except by deleting a queue.
- -->
- <field name = "auto-delete" domain = "bit" label = "auto-delete when unused">
- <doc>
- If set, the exchange is deleted when all queues have finished using it.
- </doc>
- <rule name = "sticky">
- <doc>
- The server MUST ignore the auto-delete field if the exchange already
- exists.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "internal" domain = "bit" label = "create internal exchange">
- <doc>
- If set, the exchange may not be used directly by publishers, but only when bound
- to other exchanges. Internal exchanges are used to construct wiring that is not
- visible to applications.
- </doc>
- </field>
-
- <field name = "arguments" domain = "table" label = "arguments for declaration">
- <doc>
- A set of arguments for the declaration. The syntax and semantics of these
- arguments depends on the server implementation. This field is ignored if passive
- is 1.
- </doc>
- </field>
- </method>
-
- <method name = "declare-ok" synchronous = "1" index = "11" label = "confirm exchange declaration">
- <doc>
- This method confirms a Declare method and confirms the name of the exchange,
- essential for automatically-named exchanges.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "delete" synchronous = "1" index = "20" label = "delete an exchange">
- <doc>
- This method deletes an exchange. When an exchange is deleted all queue bindings on
- the exchange are cancelled.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "delete-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "active" access
- rights to the exchange's access realm.
- </doc>
- <doc type = "scenario">
- Client creates access ticket with wrong access rights and attempts to use
- in this method.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <rule name = "exists" on-failure = "not-found">
- <doc>
- The client MUST NOT attempt to delete an exchange that does not exist.
- </doc>
- </rule>
- <assert check = "notnull" />
- </field>
-
- <!-- TODO 0.82 - discuss whether this option is useful or not. I don't have
- any real use case for it. /PH 2006-07-23.
- -->
- <field name = "if-unused" domain = "bit" label = "delete only if unused">
- <doc>
- If set, the server will only delete the exchange if it has no queue bindings. If
- the exchange has queue bindings the server does not delete it but raises a
- channel exception instead.
- </doc>
- </field>
- </method>
-
- <method name = "delete-ok" synchronous = "1" index = "21"
- label = "confirm deletion of an exchange">
- <doc>This method confirms the deletion of an exchange.</doc>
- <chassis name = "client" implement = "MUST" />
- </method>
- </class>
-
- <!-- == QUEUE ============================================================ -->
-
- <class name = "queue" handler = "channel" index = "50" label = "work with queues">
- <doc>
- Queues store and forward messages. Queues can be configured in the server or created at
- runtime. Queues must be attached to at least one exchange in order to receive messages
- from publishers.
- </doc>
-
- <doc type = "grammar">
- queue = C:DECLARE S:DECLARE-OK
- / C:BIND S:BIND-OK
- / C:PURGE S:PURGE-OK
- / C:DELETE S:DELETE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <rule name = "any-content">
- <doc>
- A server MUST allow any content class to be sent to any queue, in any mix, and
- queue and deliver these content classes independently. Note that all methods
- that fetch content off queues are specific to a given content class.
- </doc>
- <doc type = "scenario">
- Client creates an exchange of each standard type and several queues that
- it binds to each exchange. It must then sucessfully send each of the standard
- content types to each of the available queues.
- </doc>
- </rule>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "declare" synchronous = "1" index = "10" label = "declare queue, create if needed">
- <doc>
- This method creates or checks a queue. When creating a new queue the client can
- specify various properties that control the durability of the queue and its
- contents, and the level of sharing for the queue.
- </doc>
-
- <rule name = "default-binding">
- <doc>
- The server MUST create a default binding for a newly-created queue to the
- default exchange, which is an exchange of type 'direct'.
- </doc>
- <doc type = "scenario">
- Client creates a new queue, and then without explicitly binding it to an
- exchange, attempts to send a message through the default exchange binding,
- i.e. publish a message to the empty exchange, with the queue name as routing
- key.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_35" -->
- <rule name = "minimum-queues">
- <doc>
- The server SHOULD support a minimum of 256 queues per virtual host and ideally,
- impose no limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- Client attempts to create as many queues as it can until the server reports
- an error. The resulting count must at least be 256.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "declare-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- When a client defines a new queue, this belongs to the access realm of the
- ticket used. All further work done with that queue must be done with an access
- ticket for the same realm.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "active" access to
- the realm in which the queue exists or will be created.
- </doc>
- <doc type = "scenario">
- Client creates access ticket with wrong access rights and attempts to use
- in this method.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <rule name = "default-name">
- <doc>
- The queue name MAY be empty, in which case the server MUST create a new
- queue with a unique generated name and return this to the client in the
- Declare-Ok method.
- </doc>
- <doc type = "scenario">
- Client attempts to create several queues with an empty name. The client then
- verifies that the server-assigned names are unique and different.
- </doc>
- </rule>
- <rule name = "reserved-prefix" on-failure = "not-allowed">
- <doc>
- Queue names starting with "amq." are reserved for predeclared and
- standardised server queues. A client MAY NOT attempt to declare a queue with a
- name that starts with "amq." and the passive option set to zero.
- </doc>
- <doc type = "scenario">
- A client attempts to create a queue with a name starting with "amq." and with
- the passive option set to zero.
- </doc>
- </rule>
- <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
- </field>
-
- <field name = "passive" domain = "bit" label = "do not create queue">
- <doc>
- If set, the server will not create the queue. This field allows the client
- to assert the presence of a queue without modifying the server state.
- </doc>
- <rule name = "passive" on-failure = "not-found">
- <doc>
- The client MAY ask the server to assert that a queue exists without
- creating the queue if not. If the queue does not exist, the server
- treats this as a failure.
- </doc>
- <doc type = "scenario">
- Client declares an existing queue with the passive option and expects
- the server to respond with a declare-ok. Client then attempts to declare
- a non-existent queue with the passive option, and the server must close
- the channel with the correct reply-code.
- </doc>
- </rule>
- </field>
-
- <field name = "durable" domain = "bit" label = "request a durable queue">
- <doc>
- If set when creating a new queue, the queue will be marked as durable. Durable
- queues remain active when a server restarts. Non-durable queues (transient
- queues) are purged if/when a server restarts. Note that durable queues do not
- necessarily hold persistent messages, although it does not make sense to send
- persistent messages to a transient queue.
- </doc>
- <!-- Rule test name: was "amq_queue_03" -->
- <rule name = "persistence">
- <doc>The server MUST recreate the durable queue after a restart.</doc>
-
- <!-- TODO: use 'client does something' rather than 'a client does something'. -->
- <doc type = "scenario">
- A client creates a durable queue. The server is then restarted. The client
- then attempts to send a message to the queue. The message should be successfully
- delivered.
- </doc>
- </rule>
- <!-- Rule test name: was "amq_queue_36" -->
- <rule name = "types">
- <doc>The server MUST support both durable and transient queues.</doc>
- <doc type = "scenario">
- A client creates two named queues, one durable and one transient.
- </doc>
- </rule>
- <!-- Rule test name: was "amq_queue_37" -->
- <rule name = "pre-existence">
- <doc>The server MUST ignore the durable field if the queue already exists.</doc>
- <doc type = "scenario">
- A client creates two named queues, one durable and one transient. The client
- then attempts to declare the two queues using the same names again, but reversing
- the value of the durable flag in each case. Verify that the queues still exist
- with the original durable flag values.
- <!-- TODO: but how? -->
- </doc>
- </rule>
- </field>
-
- <field name = "exclusive" domain = "bit" label = "request an exclusive queue">
- <doc>
- Exclusive queues may only be consumed from by the current connection. Setting
- the 'exclusive' flag always implies 'auto-delete'.
- </doc>
-
- <!-- Rule test name: was "amq_queue_38" -->
- <rule name = "types">
- <doc>
- The server MUST support both exclusive (private) and non-exclusive (shared)
- queues.
- </doc>
- <doc type = "scenario">
- A client creates two named queues, one exclusive and one non-exclusive.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_04" -->
- <rule name = "02" on-failure = "channel-error">
- <doc>
- The client MAY NOT attempt to declare any existing and exclusive queue
- on multiple connections.
- </doc>
- <doc type = "scenario">
- A client declares an exclusive named queue. A second client on a different
- connection attempts to declare a queue of the same name.
- </doc>
- </rule>
- </field>
-
- <field name = "auto-delete" domain = "bit" label = "auto-delete queue when unused">
- <doc>
- If set, the queue is deleted when all consumers have finished using it. Last
- consumer can be cancelled either explicitly or because its channel is closed. If
- there was no consumer ever on the queue, it won't be deleted.
- </doc>
-
- <!-- Rule test name: was "amq_queue_31" -->
- <rule name = "pre-existence">
- <doc>
- The server MUST ignore the auto-delete field if the queue already exists.
- </doc>
- <doc type = "scenario">
- A client creates two named queues, one as auto-delete and one explicit-delete.
- The client then attempts to declare the two queues using the same names again,
- but reversing the value of the auto-delete field in each case. Verify that the
- queues still exist with the original auto-delete flag values.
- <!-- TODO: but how? -->
- </doc>
- </rule>
- </field>
-
- <field name = "arguments" domain = "table" label = "arguments for declaration">
- <doc>
- A set of arguments for the declaration. The syntax and semantics of these
- arguments depends on the server implementation. This field is ignored if passive
- is 1.
- </doc>
- </field>
- </method>
-
- <method name = "declare-ok" synchronous = "1" index = "11" label = "confirms a queue definition">
- <doc>
- This method confirms a Declare method and confirms the name of the queue, essential
- for automatically-named queues.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Reports the name of the queue. If the server generated a queue name, this field
- contains that name.
- </doc>
- <assert check = "notnull" />
- </field>
-
- <field name = "message-count" domain = "long" label = "number of messages in queue">
- <doc>
- Reports the number of messages in the queue, which will be zero for
- newly-created queues.
- </doc>
- </field>
-
- <field name = "consumer-count" domain = "long" label = "number of consumers">
- <doc>
- Reports the number of active consumers for the queue. Note that consumers can
- suspend activity (Channel.Flow) in which case they do not appear in this count.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "bind" synchronous = "1" index = "20" label = "bind queue to an exchange">
- <doc>
- This method binds a queue to an exchange. Until a queue is bound it will not receive
- any messages. In a classic messaging model, store-and-forward queues are bound to a
- dest exchange and subscription queues are bound to a dest_wild exchange.
- </doc>
-
- <!-- Rule test name: was "amq_queue_25" -->
- <rule name = "duplicates">
- <doc>
- A server MUST allow ignore duplicate bindings - that is, two or more bind
- methods for a specific queue, with identical arguments - without treating these
- as an error.
- </doc>
- <doc type = "scenario">
- A client binds a named queue to an exchange. The client then repeats the bind
- (with identical arguments).
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_39" -->
- <rule name = "failure" on-failure = "??????">
- <!--
- TODO: Find correct code. The on-failure code returned should depend on why the bind
- failed. Assuming that failures owing to bad parameters are covered in the rules relating
- to those parameters, the only remaining reason for a failure would be the lack of
- server resorces or some internal error - such as too many queues open. Would these
- cases qualify as "resource error" 506 or "internal error" 541?
- -->
- <doc>If a bind fails, the server MUST raise a connection exception.</doc>
- <doc type = "scenario">
- TODO
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_12" -->
- <rule name = "transient-exchange" on-failure = "not-allowed">
- <doc>
- The server MUST NOT allow a durable queue to bind to a transient exchange.
- </doc>
- <doc type = "scenario">
- A client creates a transient exchange. The client then declares a named durable
- queue and then attempts to bind the transient exchange to the durable queue.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_13" -->
- <rule name = "durable-exchange">
- <doc>
- Bindings for durable queues are automatically durable and the server SHOULD
- restore such bindings after a server restart.
- </doc>
- <doc type = "scenario">
- A server creates a named durable queue and binds it to a durable exchange. The
- server is restarted. The client then attempts to use the queue/exchange combination.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_17" -->
- <rule name = "internal-exchange">
- <doc>
- If the client attempts to bind to an exchange that was declared as internal, the server
- MUST raise a connection exception with reply code 530 (not allowed).
- </doc>
- <doc type = "scenario">
- A client attempts to bind a named queue to an internal exchange.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_40" -->
- <rule name = "binding-count">
- <doc>
- The server SHOULD support at least 4 bindings per queue, and ideally, impose no
- limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- A client creates a named queue and attempts to bind it to 4 different non-internal
- exchanges.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "bind-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- The client provides a valid access ticket giving "active" access rights to the
- queue's access realm.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to bind. If the queue name is empty, refers to
- the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "empty-queue" on-failure = "not-allowed">
- <doc>
- A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e.
- empty queue name) to an exchange.
- </doc>
- <doc type = "scenario">
- A client attempts to bind with an unnamed (empty) queue name to an exchange.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_26" -->
- <rule name = "queue-existence" on-failure = "not-found">
- <doc>
- A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously
- declared) to an exchange.
- </doc>
- <doc type = "scenario">
- A client attempts to bind an undeclared queue name to an exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name" label = "name of the exchange to bind to">
- <!-- Rule test name: was "amq_queue_14" -->
- <rule name = "exchange-existence" on-failure = "not-found">
- <doc>
- A client MUST NOT be allowed to bind a queue to a non-existent exchange.
- </doc>
- <doc type = "scenario">
- A client attempts to bind an named queue to a undeclared exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "message routing key">
- <doc>
- Specifies the routing key for the binding. The routing key is used for routing
- messages depending on the exchange configuration. Not all exchanges use a
- routing key - refer to the specific exchange documentation. If the queue name
- is empty, the server uses the last queue declared on the channel. If the
- routing key is also empty, the server uses this queue name for the routing
- key as well. If the queue name is provided but the routing key is empty, the
- server does the binding with that empty routing key. The meaning of empty
- routing keys depends on the exchange implementation.
- </doc>
- </field>
-
- <field name = "arguments" domain = "table" label = "arguments for binding">
- <doc>
- A set of arguments for the binding. The syntax and semantics of these arguments
- depends on the exchange class.
- </doc>
- </field>
- </method>
-
- <method name = "bind-ok" synchronous = "1" index = "21" label = "confirm bind successful">
- <doc>This method confirms that the bind was successful.</doc>
-
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "purge" synchronous = "1" index = "30" label = "purge a queue">
- <doc>
- This method removes all messages from a queue. It does not cancel consumers. Purged
- messages are deleted without any formal "undo" mechanism.
- </doc>
-
- <!-- Rule test name: was "amq_queue_15" -->
- <rule name = "01">
- <doc>A call to purge MUST result in an empty queue.</doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_41" -->
- <rule name = "02">
- <doc>
- On transacted channels the server MUST not purge messages that have already been
- sent to a client but not yet acknowledged.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <!-- Rule test name: was "amq_queue_42" -->
- <rule name = "03">
- <doc>
- The server MAY implement a purge queue or log that allows system administrators
- to recover accidentally-purged messages. The server SHOULD NOT keep purged
- messages in the same storage spaces as the live messages since the volumes of
- purged messages may get very large.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "purge-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>The access ticket must be for the access realm that holds the queue.</doc>
-
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the queue's access realm. Note that purging a queue is equivalent to reading
- all messages and discarding them.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to purge. If the queue name is empty, refers to
- the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
-
- <!-- TODO Rule split? -->
-
- <!-- Rule test name: was "amq_queue_16" -->
- <rule name = "02">
- <doc>
- The queue MUST exist. Attempting to purge a non-existing queue MUST cause a
- channel exception.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "purge-ok" synchronous = "1" index = "31" label = "confirms a queue purge">
- <doc>This method confirms the purge of a queue.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "message-count" domain = "long" label = "number of messages purged">
- <doc>Reports the number of messages purged.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "delete" synchronous = "1" index = "40" label = "delete a queue">
- <doc>
- This method deletes a queue. When a queue is deleted any pending messages are sent
- to a dead-letter queue if this is defined in the server configuration, and all
- consumers on the queue are cancelled.
- </doc>
-
- <!-- TODO: Rule split? -->
-
- <!-- Rule test name: was "amq_queue_43" -->
- <rule name = "01">
- <doc>
- The server SHOULD use a dead-letter queue to hold messages that were pending on
- a deleted queue, and MAY provide facilities for a system administrator to move
- these messages back to an active queue.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "delete-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- The client provides a valid access ticket giving "active" access rights to the
- queue's access realm.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to delete. If the queue name is empty, refers to
- the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_21" -->
- <rule name = "02">
- <doc>
- The queue must exist. If the client attempts to delete a non-existing queue
- the server MUST raise a channel exception with reply code 404 (not found).
- </doc>
- </rule>
- </field>
-
- <field name = "if-unused" domain = "bit" label = "delete only if unused">
- <doc>
- If set, the server will only delete the queue if it has no consumers. If the
- queue has consumers the server does does not delete it but raises a channel
- exception instead.
- </doc>
-
- <!-- Rule test name: was "amq_queue_29" and "amq_queue_30" -->
- <rule name = "01">
- <doc>The server MUST respect the if-unused flag when deleting a queue.</doc>
- </rule>
- </field>
-
- <field name = "if-empty" domain = "bit" label = "delete only if empty">
- <doc>
- If set, the server will only delete the queue if it has no messages.
- </doc>
- <rule name = "01">
- <doc>
- If the queue is not empty the server MUST raise a channel exception with
- reply code 406 (precondition failed).
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "delete-ok" synchronous = "1" index = "41" label = "confirm deletion of a queue">
- <doc>This method confirms the deletion of a queue.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "message-count" domain = "long" label = "number of messages purged">
- <doc>Reports the number of messages purged.</doc>
- </field>
- </method>
- </class>
-
- <!-- == BASIC ============================================================ -->
-
- <class name = "basic" handler = "channel" index = "60" label = "work with basic content">
- <doc>
- The Basic class provides methods that support an industry-standard messaging model.
- </doc>
-
- <doc type = "grammar">
- basic = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:PUBLISH content
- / S:RETURN content
- / S:DELIVER content
- / C:GET ( S:GET-OK content / S:GET-EMPTY )
- / C:ACK
- / C:REJECT
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MAY" />
-
- <!-- Rule test name: was "amq_basic_08" -->
- <rule name = "01">
- <doc>
- The server SHOULD respect the persistent property of basic messages and
- SHOULD make a best-effort to hold persistent basic messages on a reliable
- storage mechanism.
- </doc>
- <doc type = "scenario">
- Send a persistent message to queue, stop server, restart server and then
- verify whether message is still present. Assumes that queues are durable.
- Persistence without durable queues makes no sense.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_09" -->
- <rule name = "02">
- <doc>
- The server MUST NOT discard a persistent basic message in case of a queue
- overflow.
- </doc>
- <doc type = "scenario">
- Create a queue overflow situation with persistent messages and verify that
- messages do not get lost (presumably the server will write them to disk).
- </doc>
- </rule>
-
- <rule name = "03">
- <doc>
- The server MAY use the Channel.Flow method to slow or stop a basic message
- publisher when necessary.
- </doc>
- <doc type = "scenario">
- Create a queue overflow situation with non-persistent messages and verify
- whether the server responds with Channel.Flow or not. Repeat with persistent
- messages.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_10" -->
- <rule name = "04">
- <doc>
- The server MAY overflow non-persistent basic messages to persistent
- storage.
- </doc>
- <!-- Test scenario: untestable -->
- </rule>
-
- <rule name = "05">
- <doc>
- The server MAY discard or dead-letter non-persistent basic messages on a
- priority basis if the queue size exceeds some configured limit.
- </doc>
- <!-- Test scenario: untestable -->
- </rule>
-
- <!-- Rule test name: was "amq_basic_11" -->
- <rule name = "06">
- <doc>
- The server MUST implement at least 2 priority levels for basic messages,
- where priorities 0-4 and 5-9 are treated as two distinct levels.
- </doc>
- <doc type = "scenario">
- Send a number of priority 0 messages to a queue. Send one priority 9
- message. Consume messages from the queue and verify that the first message
- received was priority 9.
- </doc>
- </rule>
-
- <rule name = "07">
- <doc>
- The server MAY implement up to 10 priority levels.
- </doc>
- <doc type = "scenario">
- Send a number of messages with mixed priorities to a queue, so that all
- priority values from 0 to 9 are exercised. A good scenario would be ten
- messages in low-to-high priority. Consume from queue and verify how many
- priority levels emerge.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_12" -->
- <rule name = "08">
- <doc>
- The server MUST deliver messages of the same priority in order irrespective of
- their individual persistence.
- </doc>
- <doc type = "scenario">
- Send a set of messages with the same priority but different persistence
- settings to a queue. Consume and verify that messages arrive in same order
- as originally published.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_13" -->
- <rule name = "09">
- <doc>
- The server MUST support automatic acknowledgements on Basic content, i.e.
- consumers with the no-ack field set to FALSE.
- </doc>
- <doc type = "scenario">
- Create a queue and a consumer using automatic acknowledgements. Publish
- a set of messages to the queue. Consume the messages and verify that all
- messages are received.
- </doc>
- </rule>
-
- <rule name = "10">
- <doc>
- The server MUST support explicit acknowledgements on Basic content, i.e.
- consumers with the no-ack field set to TRUE.
- </doc>
- <doc type = "scenario">
- Create a queue and a consumer using explicit acknowledgements. Publish a
- set of messages to the queue. Consume the messages but acknowledge only
- half of them. Disconnect and reconnect, and consume from the queue.
- Verify that the remaining messages are received.
- </doc>
- </rule>
-
- <!-- These are the properties for a Basic content -->
-
- <field name = "content-type" domain = "shortstr" label = "MIME content type" />
- <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" />
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "delivery-mode" domain = "octet" label = "non-persistent (1) or persistent (2)" />
- <field name = "priority" domain = "short" label = "message priority, 0 to 9" />
- <field name = "correlation-id" domain = "shortstr" label = "application correlation identifier" />
- <field name = "reply-to" domain = "shortstr" label = "destination to reply to" />
- <field name = "expiration" domain = "shortstr" label = "message expiration specification" />
- <field name = "timestamp" domain = "timestamp" label = "message timestamp" />
- <field name = "message-id" domain = "shortstr" label = "application message identifier" />
- <field name = "type" domain = "shortstr" label = "message type name" />
- <field name = "user-id" domain = "shortstr" label = "creating user id" />
- <field name = "app-id" domain = "shortstr" label = "creating application id" />
- <!-- This field is deprecated pending review -->
- <field name = "cluster-id" domain = "shortstr" label = "intra-cluster routing identifier" />
-
- <!-- Type diversity test -->
- <field name = "property-bit" domain = "bit" label = "Extra property for testing only" />
- <field name = "property-octet" domain = "octet" label = "Extra property for testing only" />
- <field name = "property-short" domain = "short" label = "Extra property for testing only" />
- <field name = "property-long" domain = "long" label = "Extra property for testing only" />
- <field name = "property-longlong" domain = "longlong" label = "Extra property for testing only" />
- <field name = "property-shortstr" domain = "shortstr" label = "Extra property for testing only" />
- <field name = "property-longstr" domain = "longstr" label = "Extra property for testing only" />
- <field name = "property-timestamp" domain = "timestamp" label = "Extra property for testing only" />
- <field name = "property-table" domain = "table" label = "Extra property for testing only" />
- <field name = "property-access-ticket" domain = "access-ticket" label = "Extra property for testing only" />
- <field name = "property-class-id" domain = "class-id" label = "Extra property for testing only" />
- <field name = "property-consumer-tag" domain = "consumer-tag" label = "Extra property for testing only" />
- <field name = "property-delivery-tag" domain = "delivery-tag" label = "Extra property for testing only" />
- <field name = "property-exchange-name" domain = "exchange-name" label = "Extra property for testing only" />
- <field name = "property-known-hosts" domain = "known-hosts" label = "Extra property for testing only" />
- <field name = "property-method-id" domain = "method-id" label = "Extra property for testing only" />
- <field name = "property-no-ack" domain = "no-ack" label = "Extra property for testing only" />
- <field name = "property-no-local" domain = "no-local" label = "Extra property for testing only" />
- <field name = "property-path" domain = "path" label = "Extra property for testing only" />
- <field name = "property-peer-properties" domain = "peer-properties" label = "Extra property for testing only" />
- <field name = "property-queue-name" domain = "queue-name" label = "Extra property for testing only" />
- <field name = "property-redelivered" domain = "redelivered" label = "Extra property for testing only" />
- <field name = "property-reply-code" domain = "reply-code" label = "Extra property for testing only" />
- <field name = "property-reply-text" domain = "reply-text" label = "Extra property for testing only" />
-
- <!-- Bit field test -->
- <field name = "property-long-A" domain = "long" label = "Extra property for testing only" />
- <field name = "property-bit-B" domain = "bit" label = "Extra property for testing only" />
- <field name = "property-bit-C" domain = "bit" label = "Extra property for testing only" />
- <field name = "property-bit-D" domain = "bit" label = "Extra property for testing only" />
- <field name = "property-bit-E" domain = "bit" label = "Extra property for testing only" />
- <field name = "property-bit-F" domain = "bit" label = "Extra property for testing only" />
- <field name = "property-shortstr-G" domain = "shortstr" label = "Extra property for testing only" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
- <doc>
- This method requests a specific quality of service. The QoS can be specified for the
- current channel or for all channels on the connection. The particular properties and
- semantics of a qos method always depend on the content class semantics. Though the
- qos method could in principle apply to both peers, it is currently meaningful only
- for the server.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "qos-ok" />
-
- <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
- <doc>
- The client can request that messages be sent in advance so that when the client
- finishes processing a message, the following message is already held locally,
- rather than needing to be sent down the channel. Prefetching gives a performance
- improvement. This field specifies the prefetch window size in octets. The server
- will send a message in advance if it is equal to or smaller in size than the
- available prefetch size (and also falls into other prefetch limits). May be set
- to zero, meaning "no specific limit", although other prefetch limits may still
- apply. The prefetch-size is ignored if the no-ack option is set.
- </doc>
- <!-- Rule test name: was "amq_basic_17" -->
- <rule name = "01">
- <doc>
- The server MUST ignore this setting when the client is not processing any
- messages - i.e. the prefetch size does not limit the transfer of single
- messages to a client, only the sending in advance of more messages while
- the client still has one or more unacknowledged messages.
- </doc>
- <doc type = "scenario">
- Define a QoS prefetch-size limit and send a single message that exceeds
- that limit. Verify that the message arrives correctly.
- </doc>
- </rule>
- </field>
-
- <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
- <doc>
- Specifies a prefetch window in terms of whole messages. This field may be used
- in combination with the prefetch-size field; a message will only be sent in
- advance if both prefetch windows (and those at the channel and connection level)
- allow it. The prefetch-count is ignored if the no-ack option is set.
- </doc>
- <!-- Rule test name: was "amq_basic_18" -->
- <rule name = "01">
- <doc>
- The server may send less data in advance than allowed by the client's
- specified prefetch windows but it MUST NOT send more.
- </doc>
- <doc type = "scenario">
- Define a QoS prefetch-size limit and a prefetch-count limit greater than
- one. Send multiple messages that exceed the prefetch size. Verify that
- no more than one message arrives at once.
- </doc>
- </rule>
- </field>
-
- <field name = "global" domain = "bit" label = "apply to entire connection">
- <doc>
- By default the QoS settings apply to the current channel only. If this field is
- set, they are applied to the entire connection.
- </doc>
- </field>
- </method>
-
- <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
- <doc>
- This method tells the client that the requested QoS levels could be handled by the
- server. The requested QoS applies to all active consumers until a new QoS is
- defined.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
- <doc>
- This method asks the server to start a "consumer", which is a transient request for
- messages from a specific queue. Consumers last as long as the channel they were
- created on, or until the client cancels them.
- </doc>
-
- <!-- Rule test name: was "amq_basic_01" -->
- <rule name = "01">
- <doc>
- The server SHOULD support at least 16 consumers per queue, and ideally, impose
- no limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- Create a queue and create consumers on that queue until the server closes the
- connection. Verify that the number of consumers created was at least sixteen
- and report the total number.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- <doc type = "scenario">
- Attempt to create a consumer with an invalid (non-zero) access ticket.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
- <rule name = "01" on-failure = "not-allowed">
- <doc>
- If the queue name is empty the client MUST have previously declared a
- queue using this channel.
- </doc>
- <doc type = "scenario">
- Attempt to create a consumer with an empty queue name and no previously
- declared queue on the channel.
- </doc>
- </rule>
- </field>
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is local to a
- connection, so two clients can use the same consumer tags. If this field is
- empty the server will generate a unique tag.
- </doc>
- <rule name = "01" on-failure = "not-allowed">
- <doc>
- The client MUST NOT specify a tag that refers to an existing consumer.
- </doc>
- <doc type = "scenario">
- Attempt to create two consumers with the same non-empty tag.
- </doc>
- </rule>
- <rule name = "02" on-failure = "not-allowed">
- <doc>
- The consumer tag is valid only within the channel from which the
- consumer was created. I.e. a client MUST NOT create a consumer in one
- channel and then use it in another.
- </doc>
- <doc type = "scenario">
- Attempt to create a consumer in one channel, then use in another channel,
- in which consumers have also been created (to test that the server uses
- unique consumer tags).
- </doc>
- </rule>
- </field>
-
- <field name = "no-local" domain = "no-local" />
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise
- a channel or connection exception.
- </doc>
- </field>
-
- <field name = "bit-test-1" domain = "bit" />
- <field name = "bit-test-2" domain = "bit" />
- <field name = "bit-test-3" domain = "bit" />
- <field name = "bit-test-4" domain = "bit" />
- <field name = "bit-test-5" domain = "bit" />
- <field name = "bit-test-6" domain = "bit" />
- <field name = "bit-test-7" domain = "bit" />
- <field name = "bit-test-8" domain = "bit" />
- <field name = "bit-test-9" domain = "bit" />
-
- <field name = "no-ack" domain = "short" />
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive consumer access, meaning only this consumer can access the
- queue.
- </doc>
- <!-- Rule test name: was "amq_basic_02" -->
- <rule name = "01" on-failure = "access-refused">
- <doc>
- The client MAY NOT gain exclusive access to a queue that already has
- active consumers.
- </doc>
- <doc type = "scenario">
- Open two connections to a server, and in one connection create a shared
- (non-exclusive) queue and then consume from the queue. In the second
- connection attempt to consume from the same queue using the exclusive
- option.
- </doc>
- </rule>
- </field>
-
- <field name = "priority" domain = "short" label = "consume priority"/>
- </method>
-
- <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
- <doc>
- The server provides the client with a consumer tag, which is used by the client
- for methods called on the consumer at a later stage.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Holds the consumer tag specified by the client or provided by the server.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
- <doc>
- This method cancels a consumer. This does not affect already delivered
- messages, but it does mean the server will not send any more messages for
- that consumer. The client may receive an abitrary number of messages in
- between sending the cancel method and receiving the cancel-ok reply.
- </doc>
-
- <rule name = "01">
- <doc>
- If the queue does not exist the server MUST ignore the cancel method, so
- long as the consumer tag is valid for that channel.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "cancel-ok" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
- <doc>
- This method confirms that the cancellation was completed.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "publish" content = "1" index = "40" label = "publish a message">
- <doc>
- This method publishes a message to a specific exchange. The message will be routed
- to queues as defined by the exchange configuration and distributed to any active
- consumers when the transaction, if any, is committed.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "write" access rights
- to the access realm for the exchange.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange name can be
- empty, meaning the default exchange. If the exchange name is specified, and that
- exchange does not exist, the server will raise a channel exception.
- </doc>
-
- <!-- Rule test name: was "amq_basic_06" -->
- <rule name = "01">
- <doc>
- The server MUST accept a blank exchange name to mean the default exchange.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_14" -->
- <rule name = "02">
- <doc>
- If the exchange was declared as an internal exchange, the server MUST raise
- a channel exception with a reply code 403 (access refused).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_15" -->
- <rule name = "03">
- <doc>
- The exchange MAY refuse basic content in which case it MUST raise a channel
- exception with reply code 540 (not implemented).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "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 = "mandatory" domain = "bit" label = "indicate mandatory routing">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue. If this flag is set, the server will return an unroutable message with a
- Return method. If this flag is zero, the server silently drops the message.
- </doc>
- <!-- Rule test name: was "amq_basic_07" -->
- <rule name = "01">
- <doc>
- The server SHOULD implement the mandatory flag.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "immediate" domain = "bit" label = "request immediate delivery">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue consumer immediately. If this flag is set, the server will return an
- undeliverable message with a Return method. If this flag is zero, the server
- will queue the message, but with no guarantee that it will ever be consumed.
- </doc>
- <!-- Rule test name: was "amq_basic_16" -->
- <rule name = "01">
- <doc>
- The server SHOULD implement the immediate flag.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "return" content = "1" index = "50" label = "return a failed message">
- <doc>
- This method returns an undeliverable message that was published with the "immediate"
- flag set, or an unroutable message published with the "mandatory" flag set. The
- reply code and text provide information about the reason that the message was
- undeliverable.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply-code" domain = "reply-code" />
-
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>
- Specifies the routing key name specified when the message was published.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "deliver" content = "1" index = "60"
- label = "notify the client of a consumer message">
- <doc>
- This method delivers a message to the client, via a consumer. In the asynchronous
- message delivery model, the client starts a consumer using the Consume method, then
- the server responds with Deliver methods as and when messages arrive for that
- consumer.
- </doc>
-
- <!-- Rule test name: was "amq_basic_19" -->
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server SHOULD track the number of times a message has been delivered to
- clients and when a message is redelivered a certain number of times - e.g. 5
- times - without being acknowledged, the server SHOULD consider the message to be
- unprocessable (possibly causing client applications to abort), and move the
- message to a dead letter queue.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "get" synchronous = "1" index = "70" label = "direct access to a queue">
- <doc>
- This method provides a direct access to the messages in a queue using a synchronous
- dialogue that is designed for specific types of application where synchronous
- functionality is more important than performance.
- </doc>
-
- <response name = "get-ok" />
- <response name = "get-empty" />
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "no-ack" domain = "no-ack" />
- </method>
-
- <method name = "get-ok" synchronous = "1" content = "1" index = "71"
- label = "provide client with a message">
- <doc>
- This method delivers a message to the client following a get method. A message
- delivered by 'get-ok' must be acknowledged unless the no-ack option was set in the
- get method.
- </doc>
-
- <chassis name = "client" implement = "MAY" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- If empty, the message was published to the default exchange.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
-
- <field name = "message-count" domain = "long" label = "number of messages pending">
- <doc>
- This field reports the number of messages pending on the queue, excluding the
- message being delivered. Note that this figure is indicative, not reliable, and
- can change arbitrarily as messages are added to the queue and removed by other
- clients.
- </doc>
- </field>
- </method>
-
- <method name = "get-empty" synchronous = "1" index = "72"
- label = "indicate no messages available">
- <doc>
- This method tells the client that the queue has no messages available for the
- client.
- </doc>
-
- <chassis name = "client" implement = "MAY" />
-
- <!-- This field is deprecated pending review -->
- <field name = "cluster-id" domain = "shortstr" label = "Cluster id">
- <doc>
- For use by cluster applications, should not be used by client applications.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "ack" index = "80" label = "acknowledge one or more messages">
- <doc>
- This method acknowledges one or more messages delivered via the Deliver or Get-Ok
- methods. The client can ask to confirm a single message or a set of messages up to
- and including a specific message.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "multiple" domain = "bit" label = "acknowledge multiple messages">
- <doc>
- If set to 1, the delivery tag is treated as "up to and including", so that the
- client can acknowledge multiple messages with a single method. If set to zero,
- the delivery tag refers to a single message. If the multiple field is 1, and the
- delivery tag is zero, tells the server to acknowledge all outstanding mesages.
- </doc>
-
- <!-- Rule test name: was "amq_basic_20" -->
- <rule name = "01">
- <doc>
- The server MUST validate that a non-zero delivery-tag refers to an delivered
- message, and raise a channel exception if this is not the case.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "reject" index = "90" label = "reject an incoming message">
- <doc>
- This method allows a client to reject a message. It can be used to interrupt and
- cancel large incoming messages, or return untreatable messages to their original
- queue.
- </doc>
-
- <!-- Rule test name: was "amq_basic_21" -->
- <rule name = "01">
- <doc>
- The server SHOULD be capable of accepting and process the Reject method while
- sending message content with a Deliver or Get-Ok method. I.e. the server should
- read and process incoming methods while sending output frames. To cancel a
- partially-send content, the server sends a content body frame of size 1 (i.e.
- with no data except the frame-end octet).
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_22" -->
- <rule name = "02">
- <doc>
- The server SHOULD interpret this method as meaning that the client is unable to
- process the message at this time.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <rule name = "03">
- <!-- TODO: Rule split? -->
- <doc>
- A client MUST NOT use this method as a means of selecting messages to process. A
- rejected message MAY be discarded or dead-lettered, not necessarily passed to
- another client.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "requeue" domain = "bit" label = "requeue the message">
- <doc>
- If this field is zero, the message will be discarded. If this bit is 1, the
- server will attempt to requeue the message.
- </doc>
-
- <!-- Rule test name: was "amq_basic_23" -->
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MUST NOT deliver the message to the same client within the
- context of the current channel. The recommended strategy is to attempt to
- deliver the message to an alternative consumer, and if that is not possible,
- to move the message to a dead-letter queue. The server MAY use more
- sophisticated tracking to hold the message on the queue and redeliver it to
- the same client at a later stage.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "recover" index = "100" label = "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>
-
- <rule name = "01">
- <doc>
- The server MUST set the redelivered flag on all messages that are resent.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- The server MUST raise a channel exception if this is called on a transacted
- channel.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "requeue" domain = "bit" label = "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>
- </method>
- </class>
-
- <!-- == FILE ============================================================= -->
-
- <class name = "file" handler = "channel" index = "70" label = "work with file content">
- <doc>
- The file class provides methods that support reliable file transfer. File
- messages have a specific set of properties that are required for interoperability
- with file transfer applications. File messages and acknowledgements are subject to
- channel transactions. Note that the file class does not provide message browsing
- methods; these are not compatible with the staging model. Applications that need
- browsable file transfer should use Basic content and the Basic class.
- </doc>
-
- <doc type = "grammar">
- file = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:OPEN S:OPEN-OK C:STAGE content
- / S:OPEN C:OPEN-OK S:STAGE content
- / C:PUBLISH
- / S:DELIVER
- / S:RETURN
- / C:ACK
- / C:REJECT
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <rule name = "01">
- <doc>
- The server MUST make a best-effort to hold file messages on a reliable storage
- mechanism.
- </doc>
- </rule>
-
- <!-- TODO Rule implement attr inverse? -->
-
- <!-- TODO: Rule split? -->
-
- <rule name = "02">
- <doc>
- The server MUST NOT discard a file message in case of a queue overflow. The server
- MUST use the Channel.Flow method to slow or stop a file message publisher when
- necessary.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "03">
- <doc>
- The server MUST implement at least 2 priority levels for file messages, where
- priorities 0-4 and 5-9 are treated as two distinct levels. The server MAY implement
- up to 10 priority levels.
- </doc>
- </rule>
-
- <rule name = "04">
- <doc>
- The server MUST support both automatic and explicit acknowledgements on file
- content.
- </doc>
- </rule>
-
- <!-- These are the properties for a File content -->
-
- <field name = "content-type" domain = "shortstr" label = "MIME content type" />
- <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" />
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "priority" domain = "octet" label = "message priority, 0 to 9" />
- <field name = "reply-to" domain = "shortstr" label = "destination to reply to" />
- <field name = "message-id" domain = "shortstr" label = "application message identifier" />
- <field name = "filename" domain = "shortstr" label = "message filename" />
- <field name = "timestamp" domain = "timestamp" label = "message timestamp" />
- <!-- This field is deprecated pending review -->
- <field name = "cluster-id" domain = "shortstr" label = "intra-cluster routing identifier" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
- <doc>
- This method requests a specific quality of service. The QoS can be specified for the
- current channel or for all channels on the connection. The particular properties and
- semantics of a qos method always depend on the content class semantics. Though the
- qos method could in principle apply to both peers, it is currently meaningful only
- for the server.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "qos-ok" />
-
- <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
- <doc>
- The client can request that messages be sent in advance so that when the client
- finishes processing a message, the following message is already held locally,
- rather than needing to be sent down the channel. Prefetching gives a performance
- improvement. This field specifies the prefetch window size in octets. May be set
- to zero, meaning "no specific limit". Note that other prefetch limits may still
- apply. The prefetch-size is ignored if the no-ack option is set.
- </doc>
- </field>
-
- <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
- <doc>
- Specifies a prefetch window in terms of whole messages. This is compatible with
- some file API implementations. This field may be used in combination with the
- prefetch-size field; a message will only be sent in advance if both prefetch
- windows (and those at the channel and connection level) allow it. The
- prefetch-count is ignored if the no-ack option is set.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MAY send less data in advance than allowed by the client's
- specified prefetch windows but it MUST NOT send more.
- </doc>
- </rule>
- </field>
-
- <field name = "global" domain = "bit" label = "apply to entire connection">
- <doc>
- By default the QoS settings apply to the current channel only. If this field is
- set, they are applied to the entire connection.
- </doc>
- </field>
- </method>
-
- <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
- <doc>
- This method tells the client that the requested QoS levels could be handled by the
- server. The requested QoS applies to all active consumers until a new QoS is
- defined.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
- <doc>
- This method asks the server to start a "consumer", which is a transient request for
- messages from a specific queue. Consumers last as long as the channel they were
- created on, or until the client cancels them.
- </doc>
-
- <rule name = "01">
- <doc>
- The server SHOULD support at least 16 consumers per queue, unless the queue was
- declared as private, and ideally, impose no limit except as defined by available
- resources.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is local to a
- connection, so two clients can use the same consumer tags. If this field is
- empty the server will generate a unique tag.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The tag MUST NOT refer to an existing consumer. If the client attempts to
- create two consumers with the same non-empty tag the server MUST raise a
- connection exception with reply code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "no-local" domain = "no-local" />
-
- <field name = "no-ack" domain = "no-ack" />
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive consumer access, meaning only this consumer can access the
- queue.
- </doc>
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>
- If the server cannot grant exclusive access to the queue when asked, -
- because there are other consumers active - it MUST raise a channel exception
- with return code 405 (resource locked).
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
- <doc>
- This method provides the client with a consumer tag which it MUST use in methods
- that work with the consumer.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>Holds the consumer tag specified by the client or provided by the server.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
- <doc>
- This method cancels a consumer. This does not affect already delivered messages, but
- it does mean the server will not send any more messages for that consumer.
- </doc>
-
- <response name = "cancel-ok" />
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
- <doc>This method confirms that the cancellation was completed.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "open" synchronous = "1" index = "40" label = "request to start staging">
- <doc>
- This method requests permission to start staging a message. Staging means sending
- the message into a temporary area at the recipient end and then delivering the
- message by referring to this temporary area. Staging is how the protocol handles
- partial file transfers - if a message is partially staged and the connection breaks,
- the next time the sender starts to stage it, it can restart from where it left off.
- </doc>
-
- <response name = "open-ok" />
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <field name = "identifier" domain = "shortstr" label = "staging identifier">
- <doc>
- This is the staging identifier. This is an arbitrary string chosen by the
- sender. For staging to work correctly the sender must use the same staging
- identifier when staging the same message a second time after recovery from a
- failure. A good choice for the staging identifier would be the SHA1 hash of the
- message properties data (including the original filename, revised time, etc.).
- </doc>
- </field>
-
- <field name = "content-size" domain = "longlong" label = "message content size">
- <doc>
- The size of the content in octets. The recipient may use this information to
- allocate or check available space in advance, to avoid "disk full" errors during
- staging of very large messages.
- </doc>
-
- <rule name = "01">
- <doc>
- The sender MUST accurately fill the content-size field. Zero-length content
- is permitted.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "open-ok" synchronous = "1" index = "41" label = "confirm staging ready">
- <doc>
- This method confirms that the recipient is ready to accept staged data. If the
- message was already partially-staged at a previous time the recipient will report
- the number of octets already staged.
- </doc>
-
- <response name = "stage" />
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <field name = "staged-size" domain = "longlong" label = "already staged amount">
- <doc>
- The amount of previously-staged content in octets. For a new message this will
- be zero.
- </doc>
-
- <rule name = "01">
- <doc>
- The sender MUST start sending data from this octet offset in the message,
- counting from zero.
- </doc>
- </rule>
-
- <rule name = "02">
- <!-- TODO: Rule split? -->
- <doc>
- The recipient MAY decide how long to hold partially-staged content and MAY
- implement staging by always discarding partially-staged content. However if
- it uses the file content type it MUST support the staging methods.
- </doc>
- </rule>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "stage" content = "1" index = "50" label = "stage message content">
- <doc>
- This method stages the message, sending the message content to the recipient from
- the octet offset specified in the Open-Ok method.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "publish" index = "60" label = "publish a message">
- <doc>
- This method publishes a staged file message to a specific exchange. The file message
- will be routed to queues as defined by the exchange configuration and distributed to
- any active consumers when the transaction, if any, is committed.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "write" access rights
- to the access realm for the exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange name can be
- empty, meaning the default exchange. If the exchange name is specified, and that
- exchange does not exist, the server will raise a channel exception.
- </doc>
-
- <rule name = "01">
- <doc>
- The server MUST accept a blank exchange name to mean the default exchange.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- If the exchange was declared as an internal exchange, the server MUST
- respond with a reply code 403 (access refused) and raise a channel
- exception.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "03">
- <doc>
- The exchange MAY refuse file content in which case it MUST respond with a
- reply code 540 (not implemented) and raise a channel exception.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "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 = "mandatory" domain = "bit" label = "indicate mandatory routing">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue. If this flag is set, the server will return an unroutable message with a
- Return method. If this flag is zero, the server silently drops the message.
- </doc>
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the mandatory flag.</doc>
- </rule>
- </field>
-
- <field name = "immediate" domain = "bit" label = "request immediate delivery">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue consumer immediately. If this flag is set, the server will return an
- undeliverable message with a Return method. If this flag is zero, the server
- will queue the message, but with no guarantee that it will ever be consumed.
- </doc>
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the immediate flag.</doc>
- </rule>
- </field>
-
- <field name = "identifier" domain = "shortstr" label = "staging identifier">
- <doc>
- This is the staging identifier of the message to publish. The message must have
- been staged. Note that a client can send the Publish method asynchronously
- without waiting for staging to finish.
- </doc>
- </field>
- </method>
-
- <method name = "return" content = "1" index = "70" label = "return a failed message">
- <doc>
- This method returns an undeliverable message that was published with the "immediate"
- flag set, or an unroutable message published with the "mandatory" flag set. The
- reply code and text provide information about the reason that the message was
- undeliverable.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply-code" domain = "reply-code" />
-
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "deliver" index = "80" label = "notify the client of a consumer message">
- <doc>
- This method delivers a staged file message to the client, via a consumer. In the
- asynchronous message delivery model, the client starts a consumer using the Consume
- method, then the server responds with Deliver methods as and when messages arrive
- for that consumer.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server SHOULD track the number of times a message has been delivered to
- clients and when a message is redelivered a certain number of times - e.g. 5
- times - without being acknowledged, the server SHOULD consider the message to be
- unprocessable (possibly causing client applications to abort), and move the
- message to a dead letter queue.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
-
- <field name = "identifier" domain = "shortstr" label = "staging identifier">
- <doc>
- This is the staging identifier of the message to deliver. The message must have
- been staged. Note that a server can send the Deliver method asynchronously
- without waiting for staging to finish.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "ack" index = "90" label = "acknowledge one or more messages">
- <doc>
- This method acknowledges one or more messages delivered via the Deliver method. The
- client can ask to confirm a single message or a set of messages up to and including
- a specific message.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "multiple" domain = "bit" label = "acknowledge multiple messages">
- <doc>
- If set to 1, the delivery tag is treated as "up to and including", so that the
- client can acknowledge multiple messages with a single method. If set to zero,
- the delivery tag refers to a single message. If the multiple field is 1, and the
- delivery tag is zero, tells the server to acknowledge all outstanding mesages.
- </doc>
-
- <rule name = "01">
- <doc>
- The server MUST validate that a non-zero delivery-tag refers to an delivered
- message, and raise a channel exception if this is not the case.
- </doc>
- </rule>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "reject" index = "100" label = "reject an incoming message">
- <doc>
- This method allows a client to reject a message. It can be used to return
- untreatable messages to their original queue. Note that file content is staged
- before delivery, so the client will not use this method to interrupt delivery of a
- large message.
- </doc>
-
- <rule name = "01">
- <doc>
- The server SHOULD interpret this method as meaning that the client is unable to
- process the message at this time.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "02">
- <doc>
- A client MUST NOT use this method as a means of selecting messages to process. A
- rejected message MAY be discarded or dead-lettered, not necessarily passed to
- another client.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "requeue" domain = "bit" label = "requeue the message">
- <doc>
- If this field is zero, the message will be discarded. If this bit is 1, the
- server will attempt to requeue the message.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MUST NOT deliver the message to the same client within the
- context of the current channel. The recommended strategy is to attempt to
- deliver the message to an alternative consumer, and if that is not possible,
- to move the message to a dead-letter queue. The server MAY use more
- sophisticated tracking to hold the message on the queue and redeliver it to
- the same client at a later stage.
- </doc>
- </rule>
- </field>
- </method>
- </class>
-
- <!-- == STREAM =========================================================== -->
-
- <class name = "stream" handler = "channel" index = "80" label = "work with streaming content">
- <doc>
- The stream class provides methods that support multimedia streaming. The stream class
- uses the following semantics: one message is one packet of data; delivery is
- unacknowleged and unreliable; the consumer can specify quality of service parameters
- that the server can try to adhere to; lower-priority messages may be discarded in favour
- of high priority messages.
- </doc>
-
- <doc type = "grammar">
- stream = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:PUBLISH content
- / S:RETURN
- / S:DELIVER content
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <rule name = "01">
- <doc>
- The server SHOULD discard stream messages on a priority basis if the queue size
- exceeds some configured limit.
- </doc>
- </rule>
-
- <rule name = "02">
- <!-- TODO: Rule split? -->
- <doc>
- The server MUST implement at least 2 priority levels for stream messages, where
- priorities 0-4 and 5-9 are treated as two distinct levels. The server MAY implement
- up to 10 priority levels.
- </doc>
- </rule>
-
- <rule name = "03">
- <doc>
- The server MUST implement automatic acknowledgements on stream content. That is, as
- soon as a message is delivered to a client via a Deliver method, the server must
- remove it from the queue.
- </doc>
- </rule>
-
- <!-- These are the properties for a Stream content -->
-
- <field name = "content-type" domain = "shortstr" label = "MIME content type" />
- <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" />
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "priority" domain = "octet" label = "message priority, 0 to 9" />
- <field name = "timestamp" domain = "timestamp" label = "message timestamp" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
- <doc>
- This method requests a specific quality of service. The QoS can be specified for the
- current channel or for all channels on the connection. The particular properties and
- semantics of a qos method always depend on the content class semantics. Though the
- qos method could in principle apply to both peers, it is currently meaningful only
- for the server.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "qos-ok" />
-
- <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
- <doc>
- The client can request that messages be sent in advance so that when the client
- finishes processing a message, the following message is already held locally,
- rather than needing to be sent down the channel. Prefetching gives a performance
- improvement. This field specifies the prefetch window size in octets. May be set
- to zero, meaning "no specific limit". Note that other prefetch limits may still
- apply.
- </doc>
- </field>
-
- <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
- <doc>
- Specifies a prefetch window in terms of whole messages. This field may be used
- in combination with the prefetch-size field; a message will only be sent in
- advance if both prefetch windows (and those at the channel and connection level)
- allow it.
- </doc>
- </field>
-
- <field name = "consume-rate" domain = "long" label = "transfer rate in octets/second">
- <doc>
- Specifies a desired transfer rate in octets per second. This is usually
- determined by the application that uses the streaming data. A value of zero
- means "no limit", i.e. as rapidly as possible.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MAY ignore the prefetch values and consume rates, depending on
- the type of stream and the ability of the server to queue and/or reply it.
- The server MAY drop low-priority messages in favour of high-priority
- messages.
- </doc>
- </rule>
- </field>
-
- <field name = "global" domain = "bit" label = "apply to entire connection">
- <doc>
- By default the QoS settings apply to the current channel only. If this field is
- set, they are applied to the entire connection.
- </doc>
- </field>
- </method>
-
- <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
- <doc>
- This method tells the client that the requested QoS levels could be handled by the
- server. The requested QoS applies to all active consumers until a new QoS is
- defined.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
- <doc>
- This method asks the server to start a "consumer", which is a transient request for
- messages from a specific queue. Consumers last as long as the channel they were
- created on, or until the client cancels them.
- </doc>
-
- <rule name = "01">
- <doc>
- The server SHOULD support at least 16 consumers per queue, unless the queue was
- declared as private, and ideally, impose no limit except as defined by available
- resources.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- Streaming applications SHOULD use different channels to select different
- streaming resolutions. AMQP makes no provision for filtering and/or transforming
- streams except on the basis of priority-based selective delivery of individual
- messages.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is local to a
- connection, so two clients can use the same consumer tags. If this field is
- empty the server will generate a unique tag.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The tag MUST NOT refer to an existing consumer. If the client attempts to
- create two consumers with the same non-empty tag the server MUST raise a
- connection exception with reply code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "no-local" domain = "no-local" />
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive consumer access, meaning only this consumer can access the
- queue.
- </doc>
-
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>
- If the server cannot grant exclusive access to the queue when asked, -
- because there are other consumers active - it MUST raise a channel exception
- with return code 405 (resource locked).
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
- <doc>
- This method provides the client with a consumer tag which it may use in methods that
- work with the consumer.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>Holds the consumer tag specified by the client or provided by the server.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
- <doc>
- This method cancels a consumer. Since message delivery is asynchronous the client
- may continue to receive messages for a short while after canceling a consumer. It
- may process or discard these as appropriate.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "cancel-ok" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
- <doc>This method confirms that the cancellation was completed.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "publish" content = "1" index = "40" label = "publish a message">
- <doc>
- This method publishes a message to a specific exchange. The message will be routed
- to queues as defined by the exchange configuration and distributed to any active
- consumers as appropriate.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "write" access rights
- to the access realm for the exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange name can be
- empty, meaning the default exchange. If the exchange name is specified, and that
- exchange does not exist, the server will raise a channel exception.
- </doc>
-
- <rule name = "01">
- <doc>
- The server MUST accept a blank exchange name to mean the default exchange.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- If the exchange was declared as an internal exchange, the server MUST
- respond with a reply code 403 (access refused) and raise a channel
- exception.
- </doc>
- </rule>
-
- <rule name = "03">
- <doc>
- The exchange MAY refuse stream content in which case it MUST respond with a
- reply code 540 (not implemented) and raise a channel exception.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "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 = "mandatory" domain = "bit" label = "indicate mandatory routing">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue. If this flag is set, the server will return an unroutable message with a
- Return method. If this flag is zero, the server silently drops the message.
- </doc>
-
- <!-- Rule test name: was "amq_stream_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the mandatory flag.</doc>
- </rule>
- </field>
-
- <field name = "immediate" domain = "bit" label = "request immediate delivery">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue consumer immediately. If this flag is set, the server will return an
- undeliverable message with a Return method. If this flag is zero, the server
- will queue the message, but with no guarantee that it will ever be consumed.
- </doc>
-
- <!-- Rule test name: was "amq_stream_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the immediate flag.</doc>
- </rule>
- </field>
- </method>
-
- <method name = "return" content = "1" index = "50" label = "return a failed message">
- <doc>
- This method returns an undeliverable message that was published with the "immediate"
- flag set, or an unroutable message published with the "mandatory" flag set. The
- reply code and text provide information about the reason that the message was
- undeliverable.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply-code" domain = "reply-code" />
-
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "deliver" content = "1" index = "60"
- label = "notify the client of a consumer message">
- <doc>
- This method delivers a message to the client, via a consumer. In the asynchronous
- message delivery model, the client starts a consumer using the Consume method, then
- the server responds with Deliver methods as and when messages arrive for that
- consumer.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue that the message came from. Note that a single
- channel can start many consumers on different queues.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
- </class>
-
- <!-- == TX =============================================================== -->
-
- <class name = "tx" handler = "channel" index = "90" label = "work with standard transactions">
- <doc>
- Standard transactions provide so-called "1.5 phase commit". We can ensure that work is
- never lost, but there is a chance of confirmations being lost, so that messages may be
- resent. Applications that use standard transactions must be able to detect and ignore
- duplicate messages.
- </doc>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "01">
- <doc>
- An client using standard transactions SHOULD be able to track all messages received
- within a reasonable period, and thus detect and reject duplicates of the same
- message. It SHOULD NOT pass these to the application layer.
- </doc>
- </rule>
-
- <doc type = "grammar">
- tx = C:SELECT S:SELECT-OK
- / C:COMMIT S:COMMIT-OK
- / C:ROLLBACK S:ROLLBACK-OK
- </doc>
-
- <chassis name = "server" implement = "SHOULD" />
- <chassis name = "client" implement = "MAY" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode">
- <doc>
- This method sets the channel to use standard transactions. The client must use this
- method at least once on a channel before using the Commit or Rollback methods.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "select-ok" />
- </method>
-
- <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode">
- <doc>
- This method confirms to the client that the channel was successfully set to use
- standard transactions.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "commit" synchronous = "1" index = "20" label = "commit the current transaction">
- <doc>
- This method commits all messages published and acknowledged in the current
- transaction. A new transaction starts immediately after a commit.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "commit-ok" />
- </method>
-
- <method name = "commit-ok" synchronous = "1" index = "21" label = "confirm a successful commit">
- <doc>
- This method confirms to the client that the commit succeeded. Note that if a commit
- fails, the server raises a channel exception.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "rollback" synchronous = "1" index = "30"
- label = "abandon the current transaction">
- <doc>
- This method abandons all messages published and acknowledged in the current
- transaction. A new transaction starts immediately after a rollback.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "rollback-ok" />
- </method>
-
- <method name = "rollback-ok" synchronous = "1" index = "31" label = "confirm successful rollback">
- <doc>
- This method confirms to the client that the rollback succeeded. Note that if an
- rollback fails, the server raises a channel exception.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
- </class>
-
- <!-- == DTX ============================================================== -->
-
- <class name = "dtx" handler = "channel" index = "100" label = "work with distributed transactions">
- <doc>
- Distributed transactions provide so-called "2-phase commit". The AMQP distributed
- transaction model supports the X-Open XA architecture and other distributed transaction
- implementations. The Dtx class assumes that the server has a private communications
- channel (not AMQP) to a distributed transaction coordinator.
- </doc>
-
- <doc type = "grammar">
- dtx = C:SELECT S:SELECT-OK
- C:START S:START-OK
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode">
- <doc>
- This method sets the channel to use distributed transactions. The client must use
- this method at least once on a channel before using the Start method.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "select-ok" />
- </method>
-
- <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode">
- <doc>
- This method confirms to the client that the channel was successfully set to use
- distributed transactions.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "start" synchronous = "1" index = "20"
- label = "start a new distributed transaction">
- <doc>
- This method starts a new distributed transaction. This must be the first method on a
- new channel that uses the distributed transaction mode, before any methods that
- publish or consume messages.
- </doc>
- <chassis name = "server" implement = "MAY" />
- <response name = "start-ok" />
- <field name = "dtx-identifier" domain = "shortstr" label = "transaction identifier">
- <doc>
- The distributed transaction key. This identifies the transaction so that the
- AMQP server can coordinate with the distributed transaction coordinator.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
-
- <method name = "start-ok" synchronous = "1" index = "21"
- label = "confirm the start of a new distributed transaction">
- <doc>
- This method confirms to the client that the transaction started. Note that if a
- start fails, the server raises a channel exception.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
- </class>
-
- <!-- == TUNNEL =========================================================== -->
-
- <class name = "tunnel" handler = "tunnel" index = "110" label = "methods for protocol tunneling">
- <doc>
- The tunnel methods are used to send blocks of binary data - which can be serialised AMQP
- methods or other protocol frames - between AMQP peers.
- </doc>
-
- <doc type = "grammar">
- tunnel = C:REQUEST
- / S:REQUEST
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "proxy-name" domain = "shortstr" label = "identity of tunnelling proxy" />
- <field name = "data-name" domain = "shortstr" label = "name or type of message being tunnelled" />
- <field name = "durable" domain = "octet" label = "message durability indicator" />
- <field name = "broadcast" domain = "octet" label = "message broadcast mode" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "request" content = "1" index = "10" label = "sends a tunnelled method">
- <doc>
- This method tunnels a block of binary data, which can be an encoded
- AMQP method or other data. The binary data is sent as the content for
- the Tunnel.Request method.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <field name = "meta-data" domain = "table" label = "meta data for the tunnelled block">
- <doc>
- This field table holds arbitrary meta-data that the sender needs to
- pass to the recipient.
- </doc>
- </field>
- </method>
- </class>
-</amqp>
diff --git a/gentools/xml-src/amqp-0.8.test.xml b/gentools/xml-src/amqp-0.8.test.xml
deleted file mode 100644
index b0adf31828..0000000000
--- a/gentools/xml-src/amqp-0.8.test.xml
+++ /dev/null
@@ -1,3959 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
- Copyright Notice
- ================
- (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
- iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc.,
- TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
-
- License
- =======
- JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix
- Corporation, IONA\ufffd Technologies, Red Hat, Inc., TWIST Process Innovations, and
- 29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
- perpetual, royalty-free, nontransferable, nonexclusive license to
- (i) copy, display, and implement the Advanced Messaging Queue Protocol
- ("AMQP") Specification and (ii) the Licensed Claims that are held by
- the Authors, all for the purpose of implementing the Advanced Messaging
- Queue Protocol Specification. Your license and any rights under this
- Agreement will terminate immediately without notice from
- any Author if you bring any claim, suit, demand, or action related to
- the Advanced Messaging Queue Protocol Specification against any Author.
- Upon termination, you shall destroy all copies of the Advanced Messaging
- Queue Protocol Specification in your possession or control.
-
- As used hereunder, "Licensed Claims" means those claims of a patent or
- patent application, throughout the world, excluding design patents and
- design registrations, owned or controlled, or that can be sublicensed
- without fee and in compliance with the requirements of this
- Agreement, by an Author or its affiliates now or at any
- future time and which would necessarily be infringed by implementation
- of the Advanced Messaging Queue Protocol Specification. A claim is
- necessarily infringed hereunder only when it is not possible to avoid
- infringing it because there is no plausible non-infringing alternative
- for implementing the required portions of the Advanced Messaging Queue
- Protocol Specification. Notwithstanding the foregoing, Licensed Claims
- shall not include any claims other than as set forth above even if
- contained in the same patent as Licensed Claims; or that read solely
- on any implementations of any portion of the Advanced Messaging Queue
- Protocol Specification that are not required by the Advanced Messaging
- Queue Protocol Specification, or that, if licensed, would require a
- payment of royalties by the licensor to unaffiliated third parties.
- Moreover, Licensed Claims shall not include (i) any enabling technologies
- that may be necessary to make or use any Licensed Product but are not
- themselves expressly set forth in the Advanced Messaging Queue Protocol
- Specification (e.g., semiconductor manufacturing technology, compiler
- technology, object oriented technology, networking technology, operating
- system technology, and the like); or (ii) the implementation of other
- published standards developed elsewhere and merely referred to in the
- body of the Advanced Messaging Queue Protocol Specification, or
- (iii) any Licensed Product and any combinations thereof the purpose or
- function of which is not required for compliance with the Advanced
- Messaging Queue Protocol Specification. For purposes of this definition,
- the Advanced Messaging Queue Protocol Specification shall be deemed to
- include both architectural and interconnection requirements essential
- for interoperability and may also include supporting source code artifacts
- where such architectural, interconnection requirements and source code
- artifacts are expressly identified as being required or documentation to
- achieve compliance with the Advanced Messaging Queue Protocol Specification.
-
- As used hereunder, "Licensed Products" means only those specific portions
- of products (hardware, software or combinations thereof) that implement
- and are compliant with all relevant portions of the Advanced Messaging
- Queue Protocol Specification.
-
- The following disclaimers, which you hereby also acknowledge as to any
- use you may make of the Advanced Messaging Queue Protocol Specification:
-
- THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
- AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
- IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
- CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
- SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
- MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY
- PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
-
- THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
- INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
- USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
- PROTOCOL SPECIFICATION.
-
- The name and trademarks of the Authors may NOT be used in any manner,
- including advertising or publicity pertaining to the Advanced Messaging
- Queue Protocol Specification or its contents without specific, written
- prior permission. Title to copyright in the Advanced Messaging Queue
- Protocol Specification will at all times remain with the Authors.
-
- No other rights are granted by implication, estoppel or otherwise.
-
- Upon termination of your license or rights under this Agreement, you
- shall destroy all copies of the Advanced Messaging Queue Protocol
- Specification in your possession or control.
-
- Trademarks
- ==========
- "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
- Octagon Symbol are trademarks of JPMorgan Chase & Co.
-
- IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
-
- IONA, IONA Technologies, and the IONA logos are trademarks of IONA
- Technologies PLC and/or its subsidiaries.
-
- LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
- trademarks of Red Hat, Inc. in the US and other countries.
-
- Java, all Java-based trademarks and OpenOffice.org are trademarks of
- Sun Microsystems, Inc. in the United States, other countries, or both.
-
- Other company, product, or service names may be trademarks or service
- marks of others.
-
- Links to full AMQP specification:
- =================================
- http://www.envoytech.org/spec/amq/
- http://www.iona.com/opensource/amqp/
- http://www.redhat.com/solutions/specifications/amqp/
- http://www.twiststandards.org/tiki-index.php?page=AMQ
- http://www.imatix.com/amqp
-
--->
-
-<!--
-========================================================
-EDITORS: (PH) Pieter Hintjens <ph@imatix.com>
- (KvdR) Kim van der Riet <kim.vdriet@redhat.com>
-
-NOTE: These editors have been assigned by the AMQP working group. Please do not
-edit/commit this file without consulting with one of the above editors.
-========================================================
-
-Revision history:
- 2006-06-07 (PH) - version number changed to 0.8 to conform to public
- release documentation.
-
- 2006-05-15 (PH) - fixed comments on queue name in basic.get to clarify
- use of current queue in this method.
-
- 2006-05-15 (PH) - fixed comments on routing key in queue.bind to clarify
- how routing key is filled when empty (to allow asynch queue.declare).
-
- 2006-05-11 (PH) - reset version to 0.70 so that putatitive standards
- group can release 2-3 major new versions before hitting 1.0 (again).
-
- 2006-05-11 (PH) - TODO in documentation: cycle field in frame header
- has been removed.
-
- 2006-05-11 (PH) - added nowait option to exchange.declare, delete,
- queue.declare, delete, bind, purge, basic.consume, cancel,
- file.consume, cancel, stream.consume and cancel methods.
-
- 2006-05-11 (PH) - removed notnull rule and added explanations on queue
- name in queue.bind, purge, delete, basic.consume, cancel, file.consume,
- cancel, stream.consume and cancel methods.
-
- 2006-05-11 (PH) - added basic.qos, file.qos, and stream.qos methods that
- regroup all prefetch options from the consume methods. Also removed the
- prefetch option from channel.open.
-
- 2006-05-11 (PH) - renumbered method indexes to show request-response
- nature of methods; requests are 10, 20, 30 while responses are 11, 21,
- etc.
-
- 2006-05-11 (PH) - removed OpenAMQ extension methods from this definition
- since these are maintained seperately.
-
- 2006-05-26 (RG) - added Basic.Recover method to allow replay of
- unacknowledged messages on a channel.
-
- 2006-07-03 (PH) - cosmetic clean-up of Basic.Recover comments.
--->
-
-<amqp major="8" minor="0" port="5672" comment="AMQ protocol 0.80">
- AMQ Protocol 0.80
-
-<!--
-======================================================
-== CONSTANTS
-======================================================
--->
- <constant name="frame method" value="1"/>
- <constant name="frame header" value="2"/>
- <constant name="frame body" value="3"/>
- <constant name="frame oob method" value="4"/>
- <constant name="frame oob header" value="5"/>
- <constant name="frame oob body" value="6"/>
- <constant name="frame trace" value="7"/>
- <constant name="frame heartbeat" value="8"/>
- <constant name="frame min size" value="4096"/>
- <constant name="frame end" value="206"/>
- <constant name="reply success" value="200">
- Indicates that the method completed successfully. This reply code is
- reserved for future use - the current protocol design does not use
- positive confirmation and reply codes are sent only in case of an
- error.
-</constant>
- <constant name="not delivered" value="310" class="soft error">
- The client asked for a specific message that is no longer available.
- The message was delivered to another client, or was purged from the
- queue for some other reason.
-</constant>
- <constant name="content too large" value="311" class="soft error">
- The client attempted to transfer content larger than the server
- could accept at the present time. The client may retry at a later
- time.
-</constant>
- <constant name="connection forced" value="320" class="hard error">
- An operator intervened to close the connection for some reason.
- The client may retry at some later date.
-</constant>
- <constant name="invalid path" value="402" class="hard error">
- The client tried to work with an unknown virtual host or cluster.
-</constant>
- <constant name="access refused" value="403" class="soft error">
- The client attempted to work with a server entity to which it has
- no due to security settings.
-</constant>
- <constant name="not found" value="404" class="soft error">
- The client attempted to work with a server entity that does not exist.
-</constant>
- <constant name="resource locked" value="405" class="soft error">
- The client attempted to work with a server entity to which it has
- no access because another client is working with it.
-</constant>
- <constant name="frame error" value="501" class="hard error">
- The client sent a malformed frame that the server could not decode.
- This strongly implies a programming error in the client.
-</constant>
- <constant name="syntax error" value="502" class="hard error">
- The client sent a frame that contained illegal values for one or more
- fields. This strongly implies a programming error in the client.
-</constant>
- <constant name="command invalid" value="503" class="hard error">
- The client sent an invalid sequence of frames, attempting to perform
- an operation that was considered invalid by the server. This usually
- implies a programming error in the client.
-</constant>
- <constant name="channel error" value="504" class="hard error">
- The client attempted to work with a channel that had not been
- correctly opened. This most likely indicates a fault in the client
- layer.
-</constant>
- <constant name="resource error" value="506" class="hard error">
- The server could not complete the method because it lacked sufficient
- resources. This may be due to the client creating too many of some
- type of entity.
-</constant>
- <constant name="not allowed" value="530" class="hard error">
- The client tried to work with some entity in a manner that is
- prohibited by the server, due to security settings or by some other
- criteria.
-</constant>
- <constant name="not implemented" value="540" class="hard error">
- The client tried to use functionality that is not implemented in the
- server.
-</constant>
- <constant name="internal error" value="541" class="hard error">
- The server could not complete the method because of an internal error.
- The server may require intervention by an operator in order to resume
- normal operations.
-</constant>
- <!--
-======================================================
-== DOMAIN TYPES
-======================================================
--->
- <domain name="access ticket" type="short">
- access ticket granted by server
- <doc>
- An access ticket granted by the server for a certain set of access
- rights within a specific realm. Access tickets are valid within the
- channel where they were created, and expire when the channel closes.
- </doc>
- <assert check="ne" value="0"/>
- </domain>
- <domain name="class id" type="short"/>
- <domain name="consumer tag" type="shortstr">
- consumer tag
- <doc>
- Identifier for the consumer, valid within the current connection.
- </doc>
- <rule implement="MUST">
- The consumer tag is valid only within the channel from which the
- consumer was created. I.e. a client MUST NOT create a consumer in
- one channel and then use it in another.
- </rule>
- </domain>
- <domain name="delivery tag" type="longlong">
- server-assigned delivery tag
- <doc>
- The server-assigned and channel-specific delivery tag
- </doc>
- <rule implement="MUST">
- The delivery tag is valid only within the channel from which the
- message was received. I.e. a client MUST NOT receive a message on
- one channel and then acknowledge it on another.
- </rule>
- <rule implement="MUST">
- The server MUST NOT use a zero value for delivery tags. Zero is
- reserved for client use, meaning "all messages so far received".
- </rule>
- </domain>
- <domain name="exchange name" type="shortstr">
- exchange name
- <doc>
- The exchange name is a client-selected string that identifies
- the exchange for publish methods. Exchange names may consist
- of any mixture of digits, letters, and underscores. Exchange
- names are scoped by the virtual host.
- </doc>
- <assert check="length" value="127"/>
- </domain>
- <domain name="known hosts" type="shortstr">
-list of known hosts
-<doc>
-Specifies the list of equivalent or alternative hosts that the server
-knows about, which will normally include the current server itself.
-Clients can cache this information and use it when reconnecting to a
-server after a failure.
-</doc>
- <rule implement="MAY">
-The server MAY leave this field empty if it knows of no other
-hosts than itself.
-</rule>
- </domain>
- <domain name="method id" type="short"/>
- <domain name="no ack" type="bit">
- no acknowledgement needed
- <doc>
- If this field is set the server does not expect acknowledgments
- for messages. That is, when a message is delivered to the client
- the server automatically and silently acknowledges it on behalf
- of the client. This functionality increases performance but at
- the cost of reliability. Messages can get lost if a client dies
- before it can deliver them to the application.
- </doc>
- </domain>
- <domain name="no local" type="bit">
- do not deliver own messages
- <doc>
- If the no-local field is set the server will not send messages to
- the client that published them.
- </doc>
- </domain>
- <domain name="path" type="shortstr">
- <doc>
- Must start with a slash "/" and continue with path names
- separated by slashes. A path name consists of any combination
- of at least one of [A-Za-z0-9] plus zero or more of [.-_+!=:].
-</doc>
- <assert check="notnull"/>
- <assert check="syntax" rule="path"/>
- <assert check="length" value="127"/>
- </domain>
- <domain name="peer properties" type="table">
- <doc>
-This string provides a set of peer properties, used for
-identification, debugging, and general information.
-</doc>
- <rule implement="SHOULD">
-The properties SHOULD contain these fields:
-"product", giving the name of the peer product, "version", giving
-the name of the peer version, "platform", giving the name of the
-operating system, "copyright", if appropriate, and "information",
-giving other general information.
-</rule>
- </domain>
- <domain name="queue name" type="shortstr">
- queue name
- <doc>
- The queue name identifies the queue within the vhost. Queue
- names may consist of any mixture of digits, letters, and
- underscores.
- </doc>
- <assert check="length" value="127"/>
- </domain>
- <domain name="redelivered" type="bit">
- message is being redelivered
- <doc>
- This indicates that the message has been previously delivered to
- this or another client.
- </doc>
- <rule implement="SHOULD">
- The server SHOULD try to signal redelivered messages when it can.
- When redelivering a message that was not successfully acknowledged,
- the server SHOULD deliver it to the original client if possible.
- </rule>
- <rule implement="MUST">
- The client MUST NOT rely on the redelivered field but MUST take it
- as a hint that the message may already have been processed. A
- fully robust client must be able to track duplicate received messages
- on non-transacted, and locally-transacted channels.
- </rule>
- </domain>
- <domain name="reply code" type="short">
-reply code from server
-<doc>
- The reply code. The AMQ reply codes are defined in AMQ RFC 011.
-</doc>
- <assert check="notnull"/>
- </domain>
- <domain name="reply text" type="shortstr">
-localised reply text
-<doc>
- The localised reply text. This text can be logged as an aid to
- resolving issues.
-</doc>
- <assert check="notnull"/>
- </domain>
- <class name="connection" handler="connection" index="10">
- <!--
-======================================================
-== CONNECTION
-======================================================
--->
- work with socket connections
-<doc>
- The connection class provides methods for a client to establish a
- network connection to a server, and for both peers to operate the
- connection thereafter.
-</doc>
- <doc name="grammar">
- connection = open-connection *use-connection close-connection
- open-connection = C:protocol-header
- S:START C:START-OK
- *challenge
- S:TUNE C:TUNE-OK
- C:OPEN S:OPEN-OK | S:REDIRECT
- challenge = S:SECURE C:SECURE-OK
- use-connection = *channel
- close-connection = C:CLOSE S:CLOSE-OK
- / S:CLOSE C:CLOSE-OK
-</doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="start" synchronous="1" index="10">
- start connection negotiation
- <doc>
- This method starts the connection negotiation process by telling
- the client the protocol version that the server proposes, along
- with a list of security mechanisms which the client can use for
- authentication.
- </doc>
- <rule implement="MUST">
- If the client cannot handle the protocol version suggested by the
- server it MUST close the socket connection.
- </rule>
- <rule implement="MUST">
- The server MUST provide a protocol version that is lower than or
- equal to that requested by the client in the protocol header. If
- the server cannot support the specified protocol it MUST NOT send
- this method, but MUST close the socket connection.
- </rule>
- <chassis name="client" implement="MUST"/>
- <response name="start-ok"/>
- <field name="version major" type="octet">
- protocol major version
- <doc>
- The protocol major version that the server agrees to use, which
- cannot be higher than the client's major version.
- </doc>
- </field>
- <field name="version minor" type="octet">
- protocol major version
- <doc>
- The protocol minor version that the server agrees to use, which
- cannot be higher than the client's minor version.
- </doc>
- </field>
- <field name="server properties" domain="peer properties">
- server properties
- </field>
- <field name="mechanisms" type="longstr">
- available security mechanisms
- <doc>
- A list of the security mechanisms that the server supports, delimited
- by spaces. Currently ASL supports these mechanisms: PLAIN.
- </doc>
- <see name="security mechanisms"/>
- <assert check="notnull"/>
- </field>
- <field name="locales" type="longstr">
- available message locales
- <doc>
- A list of the message locales that the server supports, delimited
- by spaces. The locale defines the language in which the server
- will send reply texts.
- </doc>
- <rule implement="MUST">
- All servers MUST support at least the en_US locale.
- </rule>
- <assert check="notnull"/>
- </field>
- </method>
- <method name="start-ok" synchronous="1" index="11">
- select security mechanism and locale
- <doc>
- This method selects a SASL security mechanism. ASL uses SASL
- (RFC2222) to negotiate authentication and encryption.
- </doc>
- <chassis name="server" implement="MUST"/>
- <field name="client properties" domain="peer properties">
- client properties
- </field>
- <field name="mechanism" type="shortstr">
- selected security mechanism
- <doc>
- A single security mechanisms selected by the client, which must be
- one of those specified by the server.
- </doc>
- <rule implement="SHOULD">
- The client SHOULD authenticate using the highest-level security
- profile it can handle from the list provided by the server.
- </rule>
- <rule implement="MUST">
- The mechanism field MUST contain one of the security mechanisms
- proposed by the server in the Start method. If it doesn't, the
- server MUST close the socket.
- </rule>
- <assert check="notnull"/>
- </field>
- <field name="response" type="longstr">
- security response data
- <doc>
- A block of opaque data passed to the security mechanism. The contents
- of this data are defined by the SASL security mechanism. For the
- PLAIN security mechanism this is defined as a field table holding
- two fields, LOGIN and PASSWORD.
- </doc>
- <assert check="notnull"/>
- </field>
- <field name="locale" type="shortstr">
- selected message locale
- <doc>
- A single message local selected by the client, which must be one
- of those specified by the server.
- </doc>
- <assert check="notnull"/>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="secure" synchronous="1" index="20">
- security mechanism challenge
- <doc>
- The SASL protocol works by exchanging challenges and responses until
- both peers have received sufficient information to authenticate each
- other. This method challenges the client to provide more information.
- </doc>
- <chassis name="client" implement="MUST"/>
- <response name="secure-ok"/>
- <field name="challenge" type="longstr">
- security challenge data
- <doc>
- Challenge information, a block of opaque binary data passed to
- the security mechanism.
- </doc>
- <see name="security mechanisms"/>
- </field>
- </method>
- <method name="secure-ok" synchronous="1" index="21">
- security mechanism response
- <doc>
- This method attempts to authenticate, passing a block of SASL data
- for the security mechanism at the server side.
- </doc>
- <chassis name="server" implement="MUST"/>
- <field name="response" type="longstr">
- security response data
- <doc>
- A block of opaque data passed to the security mechanism. The contents
- of this data are defined by the SASL security mechanism.
- </doc>
- <assert check="notnull"/>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="tune" synchronous="1" index="30">
- propose connection tuning parameters
- <doc>
- This method proposes a set of connection configuration values
- to the client. The client can accept and/or adjust these.
- </doc>
- <chassis name="client" implement="MUST"/>
- <response name="tune-ok"/>
- <field name="channel max" type="short">
- proposed maximum channels
- <doc>
- The maximum total number of channels that the server allows
- per connection. Zero means that the server does not impose a
- fixed limit, but the number of allowed channels may be limited
- by available server resources.
- </doc>
- </field>
- <field name="frame max" type="long">
- proposed maximum frame size
- <doc>
- The largest frame size that the server proposes for the
- connection. The client can negotiate a lower value. Zero means
- that the server does not impose any specific limit but may reject
- very large frames if it cannot allocate resources for them.
- </doc>
- <rule implement="MUST">
- Until the frame-max has been negotiated, both peers MUST accept
- frames of up to 4096 octets large. The minimum non-zero value for
- the frame-max field is 4096.
- </rule>
- </field>
- <field name="heartbeat" type="short">
- desired heartbeat delay
- <doc>
- The delay, in seconds, of the connection heartbeat that the server
- wants. Zero means the server does not want a heartbeat.
- </doc>
- </field>
- </method>
- <method name="tune-ok" synchronous="1" index="31">
- negotiate connection tuning parameters
- <doc>
- This method sends the client's connection tuning parameters to the
- server. Certain fields are negotiated, others provide capability
- information.
- </doc>
- <chassis name="server" implement="MUST"/>
- <field name="channel max" type="short">
- negotiated maximum channels
- <doc>
- The maximum total number of channels that the client will use
- per connection. May not be higher than the value specified by
- the server.
- </doc>
- <rule implement="MAY">
- The server MAY ignore the channel-max value or MAY use it for
- tuning its resource allocation.
- </rule>
- <assert check="notnull"/>
- <assert check="le" method="tune" field="channel max"/>
- </field>
- <field name="frame max" type="long">
- negotiated maximum frame size
- <doc>
- The largest frame size that the client and server will use for
- the connection. Zero means that the client does not impose any
- specific limit but may reject very large frames if it cannot
- allocate resources for them. Note that the frame-max limit
- applies principally to content frames, where large contents
- can be broken into frames of arbitrary size.
- </doc>
- <rule implement="MUST">
- Until the frame-max has been negotiated, both peers must accept
- frames of up to 4096 octets large. The minimum non-zero value for
- the frame-max field is 4096.
- </rule>
- </field>
- <field name="heartbeat" type="short">
- desired heartbeat delay
- <doc>
- The delay, in seconds, of the connection heartbeat that the client
- wants. Zero means the client does not want a heartbeat.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="open" synchronous="1" index="40">
- open connection to virtual host
- <doc>
- This method opens a connection to a virtual host, which is a
- collection of resources, and acts to separate multiple application
- domains within a server.
- </doc>
- <rule implement="MUST">
- The client MUST open the context before doing any work on the
- connection.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="open-ok"/>
- <response name="redirect"/>
- <field name="virtual host" domain="path">
- virtual host name
- <assert check="regexp" value="^[a-zA-Z0-9/-_]+$"/>
- <doc>
- The name of the virtual host to work with.
- </doc>
- <rule implement="MUST">
- If the server supports multiple virtual hosts, it MUST enforce a
- full separation of exchanges, queues, and all associated entities
- per virtual host. An application, connected to a specific virtual
- host, MUST NOT be able to access resources of another virtual host.
- </rule>
- <rule implement="SHOULD">
- The server SHOULD verify that the client has permission to access
- the specified virtual host.
- </rule>
- <rule implement="MAY">
- The server MAY configure arbitrary limits per virtual host, such
- as the number of each type of entity that may be used, per
- connection and/or in total.
- </rule>
- </field>
- <field name="capabilities" type="shortstr">
- required capabilities
- <doc>
- The client may specify a number of capability names, delimited by
- spaces. The server can use this string to how to process the
- client's connection request.
- </doc>
- </field>
- <field name="insist" type="bit">
- insist on connecting to server
- <doc>
- In a configuration with multiple load-sharing servers, the server
- may respond to a Connection.Open method with a Connection.Redirect.
- The insist option tells the server that the client is insisting on
- a connection to the specified server.
- </doc>
- <rule implement="SHOULD">
- When the client uses the insist option, the server SHOULD accept
- the client connection unless it is technically unable to do so.
- </rule>
- </field>
- </method>
- <method name="open-ok" synchronous="1" index="41">
- signal that the connection is ready
- <doc>
- This method signals to the client that the connection is ready for
- use.
- </doc>
- <chassis name="client" implement="MUST"/>
- <field name="known hosts" domain="known hosts"/>
- </method>
- <method name="redirect" synchronous="1" index="50">
- asks the client to use a different server
- <doc>
- This method redirects the client to another server, based on the
- requested virtual host and/or capabilities.
- </doc>
- <rule implement="SHOULD">
- When getting the Connection.Redirect method, the client SHOULD
- reconnect to the host specified, and if that host is not present,
- to any of the hosts specified in the known-hosts list.
- </rule>
- <chassis name="client" implement="MAY"/>
- <field name="host" type="shortstr">
- server to connect to
- <doc>
- Specifies the server to connect to. This is an IP address or a
- DNS name, optionally followed by a colon and a port number. If
- no port number is specified, the client should use the default
- port number for the protocol.
- </doc>
- <assert check="notnull"/>
- </field>
- <field name="known hosts" domain="known hosts"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="close" synchronous="1" index="60">
- request a connection close
- <doc>
- This method indicates that the sender wants to close the connection.
- This may be due to internal conditions (e.g. a forced shut-down) or
- due to an error handling a specific method, i.e. an exception. When
- a close is due to an exception, the sender provides the class and
- method id of the method which caused the exception.
- </doc>
- <rule implement="MUST">
- After sending this method any received method except the Close-OK
- method MUST be discarded.
- </rule>
- <rule implement="MAY">
- The peer sending this method MAY use a counter or timeout to
- detect failure of the other peer to respond correctly with
- the Close-OK method.
- </rule>
- <rule implement="MUST">
- When a server receives the Close method from a client it MUST
- delete all server-side resources associated with the client's
- context. A client CANNOT reconnect to a context after sending
- or receiving a Close method.
- </rule>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <response name="close-ok"/>
- <field name="reply code" domain="reply code"/>
- <field name="reply text" domain="reply text"/>
- <field name="class id" domain="class id">
- failing method class
- <doc>
- When the close is provoked by a method exception, this is the
- class of the method.
- </doc>
- </field>
- <field name="method id" domain="class id">
- failing method ID
- <doc>
- When the close is provoked by a method exception, this is the
- ID of the method.
- </doc>
- </field>
- </method>
- <method name="close-ok" synchronous="1" index="61">
- confirm a connection close
- <doc>
- This method confirms a Connection.Close method and tells the
- recipient that it is safe to release resources for the connection
- and close the socket.
- </doc>
- <rule implement="SHOULD">
- A peer that detects a socket closure without having received a
- Close-Ok handshake method SHOULD log the error.
- </rule>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- </method>
- </class>
- <class name="channel" handler="channel" index="20">
- <!--
-======================================================
-== CHANNEL
-======================================================
--->
- work with channels
-<doc>
- The channel class provides methods for a client to establish a virtual
- connection - a channel - to a server and for both peers to operate the
- virtual connection thereafter.
-</doc>
- <doc name="grammar">
- channel = open-channel *use-channel close-channel
- open-channel = C:OPEN S:OPEN-OK
- use-channel = C:FLOW S:FLOW-OK
- / S:FLOW C:FLOW-OK
- / S:ALERT
- / functional-class
- close-channel = C:CLOSE S:CLOSE-OK
- / S:CLOSE C:CLOSE-OK
-</doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="open" synchronous="1" index="10">
- open a channel for use
- <doc>
- This method opens a virtual connection (a channel).
- </doc>
- <rule implement="MUST">
- This method MUST NOT be called when the channel is already open.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="open-ok"/>
- <field name="out of band" type="shortstr">
- out-of-band settings
- <doc>
- Configures out-of-band transfers on this channel. The syntax and
- meaning of this field will be formally defined at a later date.
- </doc>
- <assert check="null"/>
- </field>
- </method>
- <method name="open-ok" synchronous="1" index="11">
- signal that the channel is ready
- <doc>
- This method signals to the client that the channel is ready for use.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="flow" synchronous="1" index="20">
- enable/disable flow from peer
- <doc>
- This method asks the peer to pause or restart the flow of content
- data. This is a simple flow-control mechanism that a peer can use
- to avoid oveflowing its queues or otherwise finding itself receiving
- more messages than it can process. Note that this method is not
- intended for window control. The peer that receives a request to
- stop sending content should finish sending the current content, if
- any, and then wait until it receives a Flow restart method.
- </doc>
- <rule implement="MAY">
- When a new channel is opened, it is active. Some applications
- assume that channels are inactive until started. To emulate this
- behaviour a client MAY open the channel, then pause it.
- </rule>
- <rule implement="SHOULD">
- When sending content data in multiple frames, a peer SHOULD monitor
- the channel for incoming methods and respond to a Channel.Flow as
- rapidly as possible.
- </rule>
- <rule implement="MAY">
- A peer MAY use the Channel.Flow method to throttle incoming content
- data for internal reasons, for example, when exchangeing data over a
- slower connection.
- </rule>
- <rule implement="MAY">
- The peer that requests a Channel.Flow method MAY disconnect and/or
- ban a peer that does not respect the request.
- </rule>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <response name="flow-ok"/>
- <field name="active" type="bit">
- start/stop content frames
- <doc>
- If 1, the peer starts sending content frames. If 0, the peer
- stops sending content frames.
- </doc>
- </field>
- </method>
- <method name="flow-ok" index="21">
- confirm a flow method
- <doc>
- Confirms to the peer that a flow command was received and processed.
- </doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <field name="active" type="bit">
- current flow setting
- <doc>
- Confirms the setting of the processed flow method: 1 means the
- peer will start sending or continue to send content frames; 0
- means it will not.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="alert" index="30">
- send a non-fatal warning message
- <doc>
- This method allows the server to send a non-fatal warning to the
- client. This is used for methods that are normally asynchronous
- and thus do not have confirmations, and for which the server may
- detect errors that need to be reported. Fatal errors are handled
- as channel or connection exceptions; non-fatal errors are sent
- through this method.
- </doc>
- <chassis name="client" implement="MUST"/>
- <field name="reply code" domain="reply code"/>
- <field name="reply text" domain="reply text"/>
- <field name="details" type="table">
- detailed information for warning
- <doc>
- A set of fields that provide more information about the
- problem. The meaning of these fields are defined on a
- per-reply-code basis (TO BE DEFINED).
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="close" synchronous="1" index="40">
- request a channel close
- <doc>
- This method indicates that the sender wants to close the channel.
- This may be due to internal conditions (e.g. a forced shut-down) or
- due to an error handling a specific method, i.e. an exception. When
- a close is due to an exception, the sender provides the class and
- method id of the method which caused the exception.
- </doc>
- <rule implement="MUST">
- After sending this method any received method except
- Channel.Close-OK MUST be discarded.
- </rule>
- <rule implement="MAY">
- The peer sending this method MAY use a counter or timeout to detect
- failure of the other peer to respond correctly with Channel.Close-OK..
- </rule>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <response name="close-ok"/>
- <field name="reply code" domain="reply code"/>
- <field name="reply text" domain="reply text"/>
- <field name="class id" domain="class id">
- failing method class
- <doc>
- When the close is provoked by a method exception, this is the
- class of the method.
- </doc>
- </field>
- <field name="method id" domain="method id">
- failing method ID
- <doc>
- When the close is provoked by a method exception, this is the
- ID of the method.
- </doc>
- </field>
- </method>
- <method name="close-ok" synchronous="1" index="41">
- confirm a channel close
- <doc>
- This method confirms a Channel.Close method and tells the recipient
- that it is safe to release resources for the channel and close the
- socket.
- </doc>
- <rule implement="SHOULD">
- A peer that detects a socket closure without having received a
- Channel.Close-Ok handshake method SHOULD log the error.
- </rule>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- </method>
- </class>
- <class name="access" handler="connection" index="30">
- <!--
-======================================================
-== ACCESS CONTROL
-======================================================
--->
- work with access tickets
-<doc>
- The protocol control access to server resources using access tickets.
- A client must explicitly request access tickets before doing work.
- An access ticket grants a client the right to use a specific set of
- resources - called a "realm" - in specific ways.
-</doc>
- <doc name="grammar">
- access = C:REQUEST S:REQUEST-OK
-</doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="request" synchronous="1" index="10">
- request an access ticket
- <doc>
- This method requests an access ticket for an access realm.
- The server responds by granting the access ticket. If the
- client does not have access rights to the requested realm
- this causes a connection exception. Access tickets are a
- per-channel resource.
- </doc>
- <rule implement="MUST">
- The realm name MUST start with either "/data" (for application
- resources) or "/admin" (for server administration resources).
- If the realm starts with any other path, the server MUST raise
- a connection exception with reply code 403 (access refused).
- </rule>
- <rule implement="MUST">
- The server MUST implement the /data realm and MAY implement the
- /admin realm. The mapping of resources to realms is not
- defined in the protocol - this is a server-side configuration
- issue.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="request-ok"/>
- <field name="realm" domain="path">
- name of requested realm
- <rule implement="MUST">
- If the specified realm is not known to the server, the server
- must raise a channel exception with reply code 402 (invalid
- path).
- </rule>
- </field>
- <field name="exclusive" type="bit">
- request exclusive access
- <doc>
- Request exclusive access to the realm. If the server cannot grant
- this - because there are other active tickets for the realm - it
- raises a channel exception.
- </doc>
- </field>
- <field name="passive" type="bit">
- request passive access
- <doc>
- Request message passive access to the specified access realm.
- Passive access lets a client get information about resources in
- the realm but not to make any changes to them.
- </doc>
- </field>
- <field name="active" type="bit">
- request active access
- <doc>
- Request message active access to the specified access realm.
- Acvtive access lets a client get create and delete resources in
- the realm.
- </doc>
- </field>
- <field name="write" type="bit">
- request write access
- <doc>
- Request write access to the specified access realm. Write access
- lets a client publish messages to all exchanges in the realm.
- </doc>
- </field>
- <field name="read" type="bit">
- request read access
- <doc>
- Request read access to the specified access realm. Read access
- lets a client consume messages from queues in the realm.
- </doc>
- </field>
- </method>
- <method name="request-ok" synchronous="1" index="11">
- grant access to server resources
- <doc>
- This method provides the client with an access ticket. The access
- ticket is valid within the current channel and for the lifespan of
- the channel.
- </doc>
- <rule implement="MUST">
- The client MUST NOT use access tickets except within the same
- channel as originally granted.
- </rule>
- <rule implement="MUST">
- The server MUST isolate access tickets per channel and treat an
- attempt by a client to mix these as a connection exception.
- </rule>
- <chassis name="client" implement="MUST"/>
- <field name="ticket" domain="access ticket"/>
- </method>
- </class>
- <class name="exchange" handler="channel" index="40">
- <!--
-======================================================
-== EXCHANGES (or "routers", if you prefer)
-== (Or matchers, plugins, extensions, agents,... Routing is just one of
-== the many fun things an exchange can do.)
-======================================================
--->
- work with exchanges
-<doc>
- Exchanges match and distribute messages across queues. Exchanges can be
- configured in the server or created at runtime.
-</doc>
- <doc name="grammar">
- exchange = C:DECLARE S:DECLARE-OK
- / C:DELETE S:DELETE-OK
-</doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <rule implement="MUST">
- <test>amq_exchange_19</test>
- The server MUST implement the direct and fanout exchange types, and
- predeclare the corresponding exchanges named amq.direct and amq.fanout
- in each virtual host. The server MUST also predeclare a direct
- exchange to act as the default exchange for content Publish methods
- and for default queue bindings.
-</rule>
- <rule implement="SHOULD">
- <test>amq_exchange_20</test>
- The server SHOULD implement the topic exchange type, and predeclare
- the corresponding exchange named amq.topic in each virtual host.
-</rule>
- <rule implement="MAY">
- <test>amq_exchange_21</test>
- The server MAY implement the system exchange type, and predeclare the
- corresponding exchanges named amq.system in each virtual host. If the
- client attempts to bind a queue to the system exchange, the server
- MUST raise a connection exception with reply code 507 (not allowed).
-</rule>
- <rule implement="MUST">
- <test>amq_exchange_22</test>
- The default exchange MUST be defined as internal, and be inaccessible
- to the client except by specifying an empty exchange name in a content
- Publish method. That is, the server MUST NOT let clients make explicit
- bindings to this exchange.
-</rule>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="declare" synchronous="1" index="10">
- declare exchange, create if needed
- <doc>
- This method creates an exchange if it does not already exist, and if the
- exchange exists, verifies that it is of the correct and expected class.
- </doc>
- <rule implement="SHOULD">
- <test>amq_exchange_23</test>
- The server SHOULD support a minimum of 16 exchanges per virtual host
- and ideally, impose no limit except as defined by available resources.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="declare-ok"/>
- <field name="ticket" domain="access ticket">
- <doc>
- When a client defines a new exchange, this belongs to the access realm
- of the ticket used. All further work done with that exchange must be
- done with an access ticket for the same realm.
- </doc>
- <rule implement="MUST">
- The client MUST provide a valid access ticket giving "active" access
- to the realm in which the exchange exists or will be created, or
- "passive" access if the if-exists flag is set.
- </rule>
- </field>
- <field name="exchange" domain="exchange name">
- <rule implement="MUST">
- <test>amq_exchange_15</test>
- Exchange names starting with "amq." are reserved for predeclared
- and standardised exchanges. If the client attempts to create an
- exchange starting with "amq.", the server MUST raise a channel
- exception with reply code 403 (access refused).
- </rule>
- <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/>
- </field>
- <field name="type" type="shortstr">
- exchange type
- <doc>
- Each exchange belongs to one of a set of exchange types implemented
- by the server. The exchange types define the functionality of the
- exchange - i.e. how messages are routed through it. It is not valid
- or meaningful to attempt to change the type of an existing exchange.
- </doc>
- <rule implement="MUST">
- <test>amq_exchange_16</test>
- If the exchange already exists with a different type, the server
- MUST raise a connection exception with a reply code 507 (not allowed).
- </rule>
- <rule implement="MUST">
- <test>amq_exchange_18</test>
- If the server does not support the requested exchange type it MUST
- raise a connection exception with a reply code 503 (command invalid).
- </rule>
- <assert check="regexp" value="^[a-zA-Z0-9-_.:]+$"/>
- </field>
- <field name="passive" type="bit">
- do not create exchange
- <doc>
- If set, the server will not create the exchange. The client can use
- this to check whether an exchange exists without modifying the server
- state.
- </doc>
- <rule implement="MUST">
- <test>amq_exchange_05</test>
- If set, and the exchange does not already exist, the server MUST
- raise a channel exception with reply code 404 (not found).
- </rule>
- </field>
- <field name="durable" type="bit">
- request a durable exchange
- <doc>
- If set when creating a new exchange, the exchange will be marked as
- durable. Durable exchanges remain active when a server restarts.
- Non-durable exchanges (transient exchanges) are purged if/when a
- server restarts.
- </doc>
- <rule implement="MUST">
- <test>amq_exchange_24</test>
- The server MUST support both durable and transient exchanges.
- </rule>
- <rule implement="MUST">
- The server MUST ignore the durable field if the exchange already
- exists.
- </rule>
- </field>
- <field name="auto delete" type="bit">
- auto-delete when unused
- <doc>
- If set, the exchange is deleted when all queues have finished
- using it.
- </doc>
- <rule implement="SHOULD">
- <test>amq_exchange_02</test>
- The server SHOULD allow for a reasonable delay between the point
- when it determines that an exchange is not being used (or no longer
- used), and the point when it deletes the exchange. At the least it
- must allow a client to create an exchange and then bind a queue to
- it, with a small but non-zero delay between these two actions.
- </rule>
- <rule implement="MUST">
- <test>amq_exchange_25</test>
- The server MUST ignore the auto-delete field if the exchange already
- exists.
- </rule>
- </field>
- <field name="internal" type="bit">
- create internal exchange
- <doc>
- If set, the exchange may not be used directly by publishers, but
- only when bound to other exchanges. Internal exchanges are used to
- construct wiring that is not visible to applications.
- </doc>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-
- <field name="arguments" type="table">
- arguments for declaration
- <doc>
- A set of arguments for the declaration. The syntax and semantics
- of these arguments depends on the server implementation. This
- field is ignored if passive is 1.
- </doc>
- </field>
- </method>
- <method name="declare-ok" synchronous="1" index="11">
- confirms an exchange declaration
- <doc>
- This method confirms a Declare method and confirms the name of the
- exchange, essential for automatically-named exchanges.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="delete" synchronous="1" index="20">
- delete an exchange
- <doc>
- This method deletes an exchange. When an exchange is deleted all queue
- bindings on the exchange are cancelled.
- </doc>
- <chassis name="server" implement="MUST"/>
- <response name="delete-ok"/>
- <field name="ticket" domain="access ticket">
- <rule implement="MUST">
- The client MUST provide a valid access ticket giving "active"
- access rights to the exchange's access realm.
- </rule>
- </field>
- <field name="exchange" domain="exchange name">
- <rule implement="MUST">
- <test>amq_exchange_11</test>
- The exchange MUST exist. Attempting to delete a non-existing exchange
- causes a channel exception.
- </rule>
- <assert check="notnull"/>
- </field>
- <field name="if unused" type="bit">
- delete only if unused
- <doc>
- If set, the server will only delete the exchange if it has no queue
- bindings. If the exchange has queue bindings the server does not
- delete it but raises a channel exception instead.
- </doc>
- <rule implement="SHOULD">
- <test>amq_exchange_12</test>
- If set, the server SHOULD delete the exchange but only if it has
- no queue bindings.
- </rule>
- <rule implement="SHOULD">
- <test>amq_exchange_13</test>
- If set, the server SHOULD raise a channel exception if the exchange is in
- use.
- </rule>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-
- </method>
- <method name="delete-ok" synchronous="1" index="21">
- confirm deletion of an exchange
- <doc>
- This method confirms the deletion of an exchange.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- </class>
- <class name="queue" handler="channel" index="50">
- <!--
-======================================================
-== QUEUES
-======================================================
--->
- work with queues
-
-<doc>
- Queues store and forward messages. Queues can be configured in the server
- or created at runtime. Queues must be attached to at least one exchange
- in order to receive messages from publishers.
-</doc>
- <doc name="grammar">
- queue = C:DECLARE S:DECLARE-OK
- / C:BIND S:BIND-OK
- / C:PURGE S:PURGE-OK
- / C:DELETE S:DELETE-OK
-</doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="MUST"/>
- <rule implement="MUST">
- <test>amq_queue_33</test>
- A server MUST allow any content class to be sent to any queue, in any
- mix, and queue and delivery these content classes independently. Note
- that all methods that fetch content off queues are specific to a given
- content class.
-</rule>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="declare" synchronous="1" index="10">
- declare queue, create if needed
- <doc>
- This method creates or checks a queue. When creating a new queue
- the client can specify various properties that control the durability
- of the queue and its contents, and the level of sharing for the queue.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_34</test>
- The server MUST create a default binding for a newly-created queue
- to the default exchange, which is an exchange of type 'direct'.
- </rule>
- <rule implement="SHOULD">
- <test>amq_queue_35</test>
- The server SHOULD support a minimum of 256 queues per virtual host
- and ideally, impose no limit except as defined by available resources.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="declare-ok"/>
- <field name="ticket" domain="access ticket">
- <doc>
- When a client defines a new queue, this belongs to the access realm
- of the ticket used. All further work done with that queue must be
- done with an access ticket for the same realm.
- </doc>
- <doc>
- The client provides a valid access ticket giving "active" access
- to the realm in which the queue exists or will be created, or
- "passive" access if the if-exists flag is set.
- </doc>
- </field>
- <field name="queue" domain="queue name">
- <rule implement="MAY">
- <test>amq_queue_10</test>
- The queue name MAY be empty, in which case the server MUST create
- a new queue with a unique generated name and return this to the
- client in the Declare-Ok method.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_32</test>
- Queue names starting with "amq." are reserved for predeclared and
- standardised server queues. If the queue name starts with "amq."
- and the passive option is zero, the server MUST raise a connection
- exception with reply code 403 (access refused).
- </rule>
- <assert check="regexp" value="^[a-zA-Z0-9-_.:]*$"/>
- </field>
- <field name="passive" type="bit">
- do not create queue
- <doc>
- If set, the server will not create the queue. The client can use
- this to check whether a queue exists without modifying the server
- state.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_05</test>
- If set, and the queue does not already exist, the server MUST
- respond with a reply code 404 (not found) and raise a channel
- exception.
- </rule>
- </field>
- <field name="durable" type="bit">
- request a durable queue
- <doc>
- If set when creating a new queue, the queue will be marked as
- durable. Durable queues remain active when a server restarts.
- Non-durable queues (transient queues) are purged if/when a
- server restarts. Note that durable queues do not necessarily
- hold persistent messages, although it does not make sense to
- send persistent messages to a transient queue.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_03</test>
- The server MUST recreate the durable queue after a restart.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_36</test>
- The server MUST support both durable and transient queues.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_37</test>
- The server MUST ignore the durable field if the queue already
- exists.
- </rule>
- </field>
- <field name="exclusive" type="bit">
- request an exclusive queue
- <doc>
- Exclusive queues may only be consumed from by the current connection.
- Setting the 'exclusive' flag always implies 'auto-delete'.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_38</test>
- The server MUST support both exclusive (private) and non-exclusive
- (shared) queues.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_04</test>
- The server MUST raise a channel exception if 'exclusive' is specified
- and the queue already exists and is owned by a different connection.
- </rule>
- </field>
- <field name="auto delete" type="bit">
- auto-delete queue when unused
- <doc>
- If set, the queue is deleted when all consumers have finished
- using it. Last consumer can be cancelled either explicitly or because
- its channel is closed. If there was no consumer ever on the queue, it
- won't be deleted.
- </doc>
- <rule implement="SHOULD">
- <test>amq_queue_02</test>
- The server SHOULD allow for a reasonable delay between the point
- when it determines that a queue is not being used (or no longer
- used), and the point when it deletes the queue. At the least it
- must allow a client to create a queue and then create a consumer
- to read from it, with a small but non-zero delay between these
- two actions. The server should equally allow for clients that may
- be disconnected prematurely, and wish to re-consume from the same
- queue without losing messages. We would recommend a configurable
- timeout, with a suitable default value being one minute.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_31</test>
- The server MUST ignore the auto-delete field if the queue already
- exists.
- </rule>
- </field>
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-
- <field name="arguments" type="table">
- arguments for declaration
- <doc>
- A set of arguments for the declaration. The syntax and semantics
- of these arguments depends on the server implementation. This
- field is ignored if passive is 1.
- </doc>
- </field>
- </method>
- <method name="declare-ok" synchronous="1" index="11">
- confirms a queue definition
- <doc>
- This method confirms a Declare method and confirms the name of the
- queue, essential for automatically-named queues.
- </doc>
- <chassis name="client" implement="MUST"/>
- <field name="queue" domain="queue name">
- <doc>
- Reports the name of the queue. If the server generated a queue
- name, this field contains that name.
- </doc>
- <assert check="notnull"/>
- </field>
- <field name="message count" type="long">
- number of messages in queue
- <doc>
- Reports the number of messages in the queue, which will be zero
- for newly-created queues.
- </doc>
- </field>
- <field name="consumer count" type="long">
- number of consumers
- <doc>
- Reports the number of active consumers for the queue. Note that
- consumers can suspend activity (Channel.Flow) in which case they
- do not appear in this count.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="bind" synchronous="1" index="20">
- bind queue to an exchange
- <doc>
- This method binds a queue to an exchange. Until a queue is
- bound it will not receive any messages. In a classic messaging
- model, store-and-forward queues are bound to a dest exchange
- and subscription queues are bound to a dest_wild exchange.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_25</test>
- A server MUST allow ignore duplicate bindings - that is, two or
- more bind methods for a specific queue, with identical arguments
- - without treating these as an error.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_39</test>
- If a bind fails, the server MUST raise a connection exception.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_12</test>
- The server MUST NOT allow a durable queue to bind to a transient
- exchange. If the client attempts this the server MUST raise a
- channel exception.
- </rule>
- <rule implement="SHOULD">
- <test>amq_queue_13</test>
- Bindings for durable queues are automatically durable and the
- server SHOULD restore such bindings after a server restart.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_17</test>
- If the client attempts to an exchange that was declared as internal,
- the server MUST raise a connection exception with reply code 530
- (not allowed).
- </rule>
- <rule implement="SHOULD">
- <test>amq_queue_40</test>
- The server SHOULD support at least 4 bindings per queue, and
- ideally, impose no limit except as defined by available resources.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="bind-ok"/>
- <field name="ticket" domain="access ticket">
- <doc>
- The client provides a valid access ticket giving "active"
- access rights to the queue's access realm.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to bind. If the queue name is
- empty, refers to the current queue for the channel, which is
- the last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue
- name in this method is empty, the server MUST raise a connection
- exception with reply code 530 (not allowed).
- </doc>
- <doc name = "rule" test = "amq_queue_26">
- If the queue does not exist the server MUST raise a channel exception
- with reply code 404 (not found).
- </doc>
- </field>
-
- <field name="exchange" domain="exchange name">
- The name of the exchange to bind to.
- <rule implement="MUST">
- <test>amq_queue_14</test>
- If the exchange does not exist the server MUST raise a channel
- exception with reply code 404 (not found).
- </rule>
- </field>
- <field name="routing key" type="shortstr">
- message routing key
- <doc>
- Specifies the routing key for the binding. The routing key is
- used for routing messages depending on the exchange configuration.
- Not all exchanges use a routing key - refer to the specific
- exchange documentation. If the routing key is empty and the queue
- name is empty, the routing key will be the current queue for the
- channel, which is the last declared queue.
- </doc>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-
- <field name="arguments" type="table">
- arguments for binding
- <doc>
- A set of arguments for the binding. The syntax and semantics of
- these arguments depends on the exchange class.
- </doc>
- </field>
- </method>
- <method name="bind-ok" synchronous="1" index="21">
- confirm bind successful
- <doc>
- This method confirms that the bind was successful.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="purge" synchronous="1" index="30">
- purge a queue
- <doc>
- This method removes all messages from a queue. It does not cancel
- consumers. Purged messages are deleted without any formal "undo"
- mechanism.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_15</test>
- A call to purge MUST result in an empty queue.
- </rule>
- <rule implement="MUST">
- <test>amq_queue_41</test>
- On transacted channels the server MUST not purge messages that have
- already been sent to a client but not yet acknowledged.
- </rule>
- <rule implement="MAY">
- <test>amq_queue_42</test>
- The server MAY implement a purge queue or log that allows system
- administrators to recover accidentally-purged messages. The server
- SHOULD NOT keep purged messages in the same storage spaces as the
- live messages since the volumes of purged messages may get very
- large.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="purge-ok"/>
- <field name="ticket" domain="access ticket">
- <doc>
- The access ticket must be for the access realm that holds the
- queue.
- </doc>
- <rule implement="MUST">
- The client MUST provide a valid access ticket giving "read" access
- rights to the queue's access realm. Note that purging a queue is
- equivalent to reading all messages and discarding them.
- </rule>
- </field>
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to purge. If the queue name is
- empty, refers to the current queue for the channel, which is
- the last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue
- name in this method is empty, the server MUST raise a connection
- exception with reply code 530 (not allowed).
- </doc>
- <doc name = "rule" test = "amq_queue_16">
- The queue must exist. Attempting to purge a non-existing queue
- causes a channel exception.
- </doc>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
- </method>
- <method name="purge-ok" synchronous="1" index="31">
- confirms a queue purge
- <doc>
- This method confirms the purge of a queue.
- </doc>
- <chassis name="client" implement="MUST"/>
- <field name="message count" type="long">
- number of messages purged
- <doc>
- Reports the number of messages purged.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="delete" synchronous="1" index="40">
- delete a queue
- <doc>
- This method deletes a queue. When a queue is deleted any pending
- messages are sent to a dead-letter queue if this is defined in the
- server configuration, and all consumers on the queue are cancelled.
- </doc>
- <rule implement="SHOULD">
- <test>amq_queue_43</test>
- The server SHOULD use a dead-letter queue to hold messages that
- were pending on a deleted queue, and MAY provide facilities for
- a system administrator to move these messages back to an active
- queue.
- </rule>
- <chassis name="server" implement="MUST"/>
- <response name="delete-ok"/>
- <field name="ticket" domain="access ticket">
- <doc>
- The client provides a valid access ticket giving "active"
- access rights to the queue's access realm.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to delete. If the queue name is
- empty, refers to the current queue for the channel, which is the
- last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue
- name in this method is empty, the server MUST raise a connection
- exception with reply code 530 (not allowed).
- </doc>
- <doc name = "rule" test = "amq_queue_21">
- The queue must exist. Attempting to delete a non-existing queue
- causes a channel exception.
- </doc>
- </field>
-
- <field name="if unused" type="bit">
- delete only if unused
- <doc>
- If set, the server will only delete the queue if it has no
- consumers. If the queue has consumers the server does does not
- delete it but raises a channel exception instead.
- </doc>
- <rule implement="MUST">
- <test>amq_queue_29</test>
- <test>amq_queue_30</test>
- The server MUST respect the if-unused flag when deleting a queue.
- </rule>
- </field>
- <field name="if empty" type="bit">
- delete only if empty
- <test>amq_queue_27</test>
- <doc>
- If set, the server will only delete the queue if it has no
- messages. If the queue is not empty the server raises a channel
- exception.
- </doc>
- </field>
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name="delete-ok" synchronous="1" index="41">
- confirm deletion of a queue
- <doc>
- This method confirms the deletion of a queue.
- </doc>
- <chassis name="client" implement="MUST"/>
- <field name="message count" type="long">
- number of messages purged
- <doc>
- Reports the number of messages purged.
- </doc>
- </field>
- </method>
- </class>
- <class name="basic" handler="channel" index="60">
- <!--
-======================================================
-== BASIC MIDDLEWARE
-======================================================
--->
- work with basic content
-<doc>
- The Basic class provides methods that support an industry-standard
- messaging model.
-</doc>
-
-<doc name = "grammar">
- basic = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:PUBLISH content
- / S:RETURN content
- / S:DELIVER content
- / C:GET ( S:GET-OK content / S:GET-EMPTY )
- / C:ACK
- / C:REJECT
-</doc>
-
-<chassis name = "server" implement = "MUST" />
-<chassis name = "client" implement = "MAY" />
-
-<doc name = "rule" test = "amq_basic_08">
- The server SHOULD respect the persistent property of basic messages
- and SHOULD make a best-effort to hold persistent basic messages on a
- reliable storage mechanism.
-</doc>
-<doc name = "rule" test = "amq_basic_09">
- The server MUST NOT discard a persistent basic message in case of a
- queue overflow. The server MAY use the Channel.Flow method to slow
- or stop a basic message publisher when necessary.
-</doc>
-<doc name = "rule" test = "amq_basic_10">
- The server MAY overflow non-persistent basic messages to persistent
- storage and MAY discard or dead-letter non-persistent basic messages
- on a priority basis if the queue size exceeds some configured limit.
-</doc>
-<doc name = "rule" test = "amq_basic_11">
- The server MUST implement at least 2 priority levels for basic
- messages, where priorities 0-4 and 5-9 are treated as two distinct
- levels. The server MAY implement up to 10 priority levels.
-</doc>
-<doc name = "rule" test = "amq_basic_12">
- The server MUST deliver messages of the same priority in order
- irrespective of their individual persistence.
-</doc>
-<doc name = "rule" test = "amq_basic_13">
- The server MUST support both automatic and explicit acknowledgements
- on Basic content.
-</doc>
-
-<!-- These are the properties for a Basic content -->
-
-<field name = "content type" type = "shortstr">
- MIME content type
-</field>
-<field name = "content encoding" type = "shortstr">
- MIME content encoding
-</field>
-<field name = "headers" type = "table">
- Message header field table
-</field>
-<field name = "delivery mode" type = "octet">
- Non-persistent (1) or persistent (2)
-</field>
-<field name = "priority" type = "octet">
- The message priority, 0 to 9
-</field>
-<field name = "correlation id" type = "shortstr">
- The application correlation identifier
-</field>
-<field name = "reply to" type = "shortstr">
- The destination to reply to
-</field>
-<field name = "expiration" type = "shortstr">
- Message expiration specification
-</field>
-<field name = "message id" type = "shortstr">
- The application message identifier
-</field>
-<field name = "timestamp" type = "timestamp">
- The message timestamp
-</field>
-<field name = "type" type = "shortstr">
- The message type name
-</field>
-<field name = "user id" type = "shortstr">
- The creating user id
-</field>
-<field name = "app id" type = "shortstr">
- The creating application id
-</field>
-<field name = "cluster id" type = "shortstr">
- Intra-cluster routing identifier
-</field>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "qos" synchronous = "1" index = "10">
- specify quality of service
- <doc>
- This method requests a specific quality of service. The QoS can
- be specified for the current channel or for all channels on the
- connection. The particular properties and semantics of a qos method
- always depend on the content class semantics. Though the qos method
- could in principle apply to both peers, it is currently meaningful
- only for the server.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "qos-ok" />
-
- <field name = "prefetch size" type = "long">
- prefetch window in octets
- <doc>
- The client can request that messages be sent in advance so that
- when the client finishes processing a message, the following
- message is already held locally, rather than needing to be sent
- down the channel. Prefetching gives a performance improvement.
- This field specifies the prefetch window size in octets. The
- server will send a message in advance if it is equal to or
- smaller in size than the available prefetch size (and also falls
- into other prefetch limits). May be set to zero, meaning "no
- specific limit", although other prefetch limits may still apply.
- The prefetch-size is ignored if the no-ack option is set.
- </doc>
- <doc name = "rule" test = "amq_basic_17">
- The server MUST ignore this setting when the client is not
- processing any messages - i.e. the prefetch size does not limit
- the transfer of single messages to a client, only the sending in
- advance of more messages while the client still has one or more
- unacknowledged messages.
- </doc>
- </field>
-
- <field name = "prefetch count" type = "short">
- prefetch window in messages
- <doc>
- Specifies a prefetch window in terms of whole messages. This
- field may be used in combination with the prefetch-size field;
- a message will only be sent in advance if both prefetch windows
- (and those at the channel and connection level) allow it.
- The prefetch-count is ignored if the no-ack option is set.
- </doc>
- <doc name = "rule" test = "amq_basic_18">
- The server MAY send less data in advance than allowed by the
- client's specified prefetch windows but it MUST NOT send more.
- </doc>
- </field>
-
- <field name = "global" type = "bit">
- apply to entire connection
- <doc>
- By default the QoS settings apply to the current channel only. If
- this field is set, they are applied to the entire connection.
- </doc>
- </field>
-</method>
-
-<method name = "qos-ok" synchronous = "1" index = "11">
- confirm the requested qos
- <doc>
- This method tells the client that the requested QoS levels could
- be handled by the server. The requested QoS applies to all active
- consumers until a new QoS is defined.
- </doc>
- <chassis name = "client" implement = "MUST" />
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "consume" synchronous = "1" index = "20">
- start a queue consumer
- <doc>
- This method asks the server to start a "consumer", which is a
- transient request for messages from a specific queue. Consumers
- last as long as the channel they were created on, or until the
- client cancels them.
- </doc>
- <doc name = "rule" test = "amq_basic_01">
- The server SHOULD support at least 16 consumers per queue, unless
- the queue was declared as private, and ideally, impose no limit
- except as defined by available resources.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "read" access
- rights to the realm for the queue.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name
- is null, refers to the current queue for the channel, which is the
- last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue name
- in this method is empty, the server MUST raise a connection exception
- with reply code 530 (not allowed).
- </doc>
- </field>
-
- <field name = "consumer tag" domain = "consumer tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is
- local to a connection, so two clients can use the same consumer
- tags. If this field is empty the server will generate a unique
- tag.
- </doc>
- <doc name = "rule" test = "todo">
- The tag MUST NOT refer to an existing consumer. If the client
- attempts to create two consumers with the same non-empty tag
- the server MUST raise a connection exception with reply code
- 530 (not allowed).
- </doc>
- </field>
-
- <field name = "no local" domain = "no local" />
-
- <field name = "no ack" domain = "no ack" />
-
- <field name = "exclusive" type = "bit">
- request exclusive access
- <doc>
- Request exclusive consumer access, meaning only this consumer can
- access the queue.
- </doc>
- <doc name = "rule" test = "amq_basic_02">
- If the server cannot grant exclusive access to the queue when asked,
- - because there are other consumers active - it MUST raise a channel
- exception with return code 403 (access refused).
- </doc>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-</method>
-
-<method name = "consume-ok" synchronous = "1" index = "21">
- confirm a new consumer
- <doc>
- The server provides the client with a consumer tag, which is used
- by the client for methods called on the consumer at a later stage.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag">
- <doc>
- Holds the consumer tag specified by the client or provided by
- the server.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "cancel" synchronous = "1" index = "30">
- end a queue consumer
- <doc test = "amq_basic_04">
- This method cancels a consumer. This does not affect already
- delivered messages, but it does mean the server will not send any
- more messages for that consumer. The client may receive an
- abitrary number of messages in between sending the cancel method
- and receiving the cancel-ok reply.
- </doc>
- <doc name = "rule" test = "todo">
- If the queue no longer exists when the client sends a cancel command,
- or the consumer has been cancelled for other reasons, this command
- has no effect.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "cancel-ok" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-</method>
-
-<method name = "cancel-ok" synchronous = "1" index = "31">
- confirm a cancelled consumer
- <doc>
- This method confirms that the cancellation was completed.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "publish" content = "1" index = "40">
- publish a message
- <doc>
- This method publishes a message to a specific exchange. The message
- will be routed to queues as defined by the exchange configuration
- and distributed to any active consumers when the transaction, if any,
- is committed.
- </doc>
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "write"
- access rights to the access realm for the exchange.
- </doc>
- </field>
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange
- name can be empty, meaning the default exchange. If the exchange
- name is specified, and that exchange does not exist, the server
- will raise a channel exception.
- </doc>
- <doc name = "rule" test = "amq_basic_06">
- The server MUST accept a blank exchange name to mean the default
- exchange.
- </doc>
- <doc name = "rule" test = "amq_basic_14">
- If the exchange was declared as an internal exchange, the server
- MUST raise a channel exception with a reply code 403 (access
- refused).
- </doc>
- <doc name = "rule" test = "amq_basic_15">
- The exchange MAY refuse basic content in which case it MUST raise
- a channel exception with reply code 540 (not implemented).
- </doc>
- </field>
-
- <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 = "mandatory" type = "bit">
- indicate mandatory routing
- <doc>
- This flag tells the server how to react if the message cannot be
- routed to a queue. If this flag is set, the server will return an
- unroutable message with a Return method. If this flag is zero, the
- server silently drops the message.
- </doc>
- <doc name = "rule" test = "amq_basic_07">
- The server SHOULD implement the mandatory flag.
- </doc>
- </field>
-
- <field name = "immediate" type = "bit">
- request immediate delivery
- <doc>
- This flag tells the server how to react if the message cannot be
- routed to a queue consumer immediately. If this flag is set, the
- server will return an undeliverable message with a Return method.
- If this flag is zero, the server will queue the message, but with
- no guarantee that it will ever be consumed.
- </doc>
- <doc name = "rule" test = "amq_basic_16">
- The server SHOULD implement the immediate flag.
- </doc>
- </field>
-</method>
-
-<method name = "return" content = "1" index = "50">
- return a failed message
- <doc>
- This method returns an undeliverable message that was published
- with the "immediate" flag set, or an unroutable message published
- with the "mandatory" flag set. The reply code and text provide
- information about the reason that the message was undeliverable.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply code" domain = "reply code" />
- <field name = "reply text" domain = "reply text" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was
- originally published to.
- </doc>
- </field>
-
- <field name = "routing key" type = "shortstr">
- Message routing key
- <doc>
- Specifies the routing key name specified when the message was
- published.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "deliver" content = "1" index = "60">
- notify the client of a consumer message
- <doc>
- This method delivers a message to the client, via a consumer. In
- the asynchronous message delivery model, the client starts a
- consumer using the Consume method, then the server responds with
- Deliver methods as and when messages arrive for that consumer.
- </doc>
- <doc name = "rule" test = "amq_basic_19">
- The server SHOULD track the number of times a message has been
- delivered to clients and when a message is redelivered a certain
- number of times - e.g. 5 times - without being acknowledged, the
- server SHOULD consider the message to be unprocessable (possibly
- causing client applications to abort), and move the message to a
- dead letter queue.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was
- originally published to.
- </doc>
- </field>
-
- <field name = "routing key" type = "shortstr">
- Message routing key
- <doc>
- Specifies the routing key name specified when the message was
- published.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "get" synchronous = "1" index = "70">
- direct access to a queue
- <doc>
- This method provides a direct access to the messages in a queue
- using a synchronous dialogue that is designed for specific types of
- application where synchronous functionality is more important than
- performance.
- </doc>
- <response name = "get-ok" />
- <response name = "get-empty" />
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "read"
- access rights to the realm for the queue.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name
- is null, refers to the current queue for the channel, which is the
- last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue name
- in this method is empty, the server MUST raise a connection exception
- with reply code 530 (not allowed).
- </doc>
- </field>
-
- <field name = "no ack" domain = "no ack" />
-</method>
-
-<method name = "get-ok" synchronous = "1" content = "1" index = "71">
- provide client with a message
- <doc>
- This method delivers a message to the client following a get
- method. A message delivered by 'get-ok' must be acknowledged
- unless the no-ack option was set in the get method.
- </doc>
- <chassis name = "client" implement = "MAY" />
-
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was originally
- published to. If empty, the message was published to the default
- exchange.
- </doc>
- </field>
-
- <field name = "routing key" type = "shortstr">
- Message routing key
- <doc>
- Specifies the routing key name specified when the message was
- published.
- </doc>
- </field>
-
- <field name = "message count" type = "long" >
- number of messages pending
- <doc>
- This field reports the number of messages pending on the queue,
- excluding the message being delivered. Note that this figure is
- indicative, not reliable, and can change arbitrarily as messages
- are added to the queue and removed by other clients.
- </doc>
- </field>
-</method>
-
-
-<method name = "get-empty" synchronous = "1" index = "72">
- indicate no messages available
- <doc>
- This method tells the client that the queue has no messages
- available for the client.
- </doc>
- <chassis name = "client" implement = "MAY" />
-
- <field name = "cluster id" type = "shortstr">
- Cluster id
- <doc>
- For use by cluster applications, should not be used by
- client applications.
- </doc>
- </field>
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "ack" index = "80">
- acknowledge one or more messages
- <doc>
- This method acknowledges one or more messages delivered via the
- Deliver or Get-Ok methods. The client can ask to confirm a
- single message or a set of messages up to and including a specific
- message.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "multiple" type = "bit">
- acknowledge multiple messages
- <doc>
- If set to 1, the delivery tag is treated as "up to and including",
- so that the client can acknowledge multiple messages with a single
- method. If set to zero, the delivery tag refers to a single
- message. If the multiple field is 1, and the delivery tag is zero,
- tells the server to acknowledge all outstanding mesages.
- </doc>
- <doc name = "rule" test = "amq_basic_20">
- The server MUST validate that a non-zero delivery-tag refers to an
- delivered message, and raise a channel exception if this is not the
- case.
- </doc>
- </field>
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "reject" index = "90">
- reject an incoming message
- <doc>
- This method allows a client to reject a message. It can be used to
- interrupt and cancel large incoming messages, or return untreatable
- messages to their original queue.
- </doc>
- <doc name = "rule" test = "amq_basic_21">
- The server SHOULD be capable of accepting and process the Reject
- method while sending message content with a Deliver or Get-Ok
- method. I.e. the server should read and process incoming methods
- while sending output frames. To cancel a partially-send content,
- the server sends a content body frame of size 1 (i.e. with no data
- except the frame-end octet).
- </doc>
- <doc name = "rule" test = "amq_basic_22">
- The server SHOULD interpret this method as meaning that the client
- is unable to process the message at this time.
- </doc>
- <doc name = "rule">
- A client MUST NOT use this method as a means of selecting messages
- to process. A rejected message MAY be discarded or dead-lettered,
- not necessarily passed to another client.
- </doc>
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "requeue" type = "bit">
- requeue the message
- <doc>
- If this field is zero, the message will be discarded. If this bit
- is 1, the server will attempt to requeue the message.
- </doc>
- <doc name = "rule" test = "amq_basic_23">
- The server MUST NOT deliver the message to the same client within
- the context of the current channel. The recommended strategy is
- to attempt to deliver the message to an alternative consumer, and
- if that is not possible, to move the message to a dead-letter
- queue. The server MAY use more sophisticated tracking to hold
- the message on the queue and redeliver it to the same client at
- a later stage.
- </doc>
- </field>
-</method>
-
-<method name = "recover" index = "100">
- 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>
-</method>
-
-</class>
-
-
- <class name="file" handler="channel" index="70">
- <!--
-======================================================
-== FILE TRANSFER
-======================================================
--->
- work with file content
-<doc>
- The file class provides methods that support reliable file transfer.
- File messages have a specific set of properties that are required for
- interoperability with file transfer applications. File messages and
- acknowledgements are subject to channel transactions. Note that the
- file class does not provide message browsing methods; these are not
- compatible with the staging model. Applications that need browsable
- file transfer should use Basic content and the Basic class.
-</doc>
-
-<doc name = "grammar">
- file = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:OPEN S:OPEN-OK C:STAGE content
- / S:OPEN C:OPEN-OK S:STAGE content
- / C:PUBLISH
- / S:DELIVER
- / S:RETURN
- / C:ACK
- / C:REJECT
-</doc>
-
-<chassis name = "server" implement = "MAY" />
-<chassis name = "client" implement = "MAY" />
-
-<doc name = "rule">
- The server MUST make a best-effort to hold file messages on a
- reliable storage mechanism.
-</doc>
-<doc name = "rule">
- The server MUST NOT discard a file message in case of a queue
- overflow. The server MUST use the Channel.Flow method to slow or stop
- a file message publisher when necessary.
-</doc>
-<doc name = "rule">
- The server MUST implement at least 2 priority levels for file
- messages, where priorities 0-4 and 5-9 are treated as two distinct
- levels. The server MAY implement up to 10 priority levels.
-</doc>
-<doc name = "rule">
- The server MUST support both automatic and explicit acknowledgements
- on file content.
-</doc>
-
-<!-- These are the properties for a File content -->
-
-<field name = "content type" type = "shortstr">
- MIME content type
-</field>
-<field name = "content encoding" type = "shortstr">
- MIME content encoding
-</field>
-<field name = "headers" type = "table">
- Message header field table
-</field>
-<field name = "priority" type = "octet">
- The message priority, 0 to 9
-</field>
-<field name = "reply to" type = "shortstr">
- The destination to reply to
-</field>
-<field name = "message id" type = "shortstr">
- The application message identifier
-</field>
-<field name = "filename" type = "shortstr">
- The message filename
-</field>
-<field name = "timestamp" type = "timestamp">
- The message timestamp
-</field>
-<field name = "cluster id" type = "shortstr">
- Intra-cluster routing identifier
-</field>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "qos" synchronous = "1" index = "10">
- specify quality of service
- <doc>
- This method requests a specific quality of service. The QoS can
- be specified for the current channel or for all channels on the
- connection. The particular properties and semantics of a qos method
- always depend on the content class semantics. Though the qos method
- could in principle apply to both peers, it is currently meaningful
- only for the server.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "qos-ok" />
-
- <field name = "prefetch size" type = "long">
- prefetch window in octets
- <doc>
- The client can request that messages be sent in advance so that
- when the client finishes processing a message, the following
- message is already held locally, rather than needing to be sent
- down the channel. Prefetching gives a performance improvement.
- This field specifies the prefetch window size in octets. May be
- set to zero, meaning "no specific limit". Note that other
- prefetch limits may still apply. The prefetch-size is ignored
- if the no-ack option is set.
- </doc>
- </field>
-
- <field name = "prefetch count" type = "short">
- prefetch window in messages
- <doc>
- Specifies a prefetch window in terms of whole messages. This
- is compatible with some file API implementations. This field
- may be used in combination with the prefetch-size field; a
- message will only be sent in advance if both prefetch windows
- (and those at the channel and connection level) allow it.
- The prefetch-count is ignored if the no-ack option is set.
- </doc>
- <doc name = "rule">
- The server MAY send less data in advance than allowed by the
- client's specified prefetch windows but it MUST NOT send more.
- </doc>
- </field>
-
- <field name = "global" type = "bit">
- apply to entire connection
- <doc>
- By default the QoS settings apply to the current channel only. If
- this field is set, they are applied to the entire connection.
- </doc>
- </field>
-</method>
-
-<method name = "qos-ok" synchronous = "1" index = "11">
- confirm the requested qos
- <doc>
- This method tells the client that the requested QoS levels could
- be handled by the server. The requested QoS applies to all active
- consumers until a new QoS is defined.
- </doc>
- <chassis name = "client" implement = "MUST" />
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "consume" synchronous = "1" index = "20">
- start a queue consumer
- <doc>
- This method asks the server to start a "consumer", which is a
- transient request for messages from a specific queue. Consumers
- last as long as the channel they were created on, or until the
- client cancels them.
- </doc>
- <doc name = "rule">
- The server SHOULD support at least 16 consumers per queue, unless
- the queue was declared as private, and ideally, impose no limit
- except as defined by available resources.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "read" access
- rights to the realm for the queue.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name
- is null, refers to the current queue for the channel, which is the
- last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue name
- in this method is empty, the server MUST raise a connection exception
- with reply code 530 (not allowed).
- </doc>
- </field>
-
- <field name = "consumer tag" domain = "consumer tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is
- local to a connection, so two clients can use the same consumer
- tags. If this field is empty the server will generate a unique
- tag.
- </doc>
- <doc name = "rule" test = "todo">
- The tag MUST NOT refer to an existing consumer. If the client
- attempts to create two consumers with the same non-empty tag
- the server MUST raise a connection exception with reply code
- 530 (not allowed).
- </doc>
- </field>
-
- <field name = "no local" domain = "no local" />
-
- <field name = "no ack" domain = "no ack" />
-
- <field name = "exclusive" type = "bit">
- request exclusive access
- <doc>
- Request exclusive consumer access, meaning only this consumer can
- access the queue.
- </doc>
- <doc name = "rule" test = "amq_file_00">
- If the server cannot grant exclusive access to the queue when asked,
- - because there are other consumers active - it MUST raise a channel
- exception with return code 405 (resource locked).
- </doc>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-</method>
-
-<method name = "consume-ok" synchronous = "1" index = "21">
- confirm a new consumer
- <doc>
- This method provides the client with a consumer tag which it MUST
- use in methods that work with the consumer.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag">
- <doc>
- Holds the consumer tag specified by the client or provided by
- the server.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "cancel" synchronous = "1" index = "30">
- end a queue consumer
- <doc>
- This method cancels a consumer. This does not affect already
- delivered messages, but it does mean the server will not send any
- more messages for that consumer.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "cancel-ok" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-</method>
-
-<method name = "cancel-ok" synchronous = "1" index = "31">
- confirm a cancelled consumer
- <doc>
- This method confirms that the cancellation was completed.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "open" synchronous = "1" index = "40">
- request to start staging
- <doc>
- This method requests permission to start staging a message. Staging
- means sending the message into a temporary area at the recipient end
- and then delivering the message by referring to this temporary area.
- Staging is how the protocol handles partial file transfers - if a
- message is partially staged and the connection breaks, the next time
- the sender starts to stage it, it can restart from where it left off.
- </doc>
- <response name = "open-ok" />
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <field name = "identifier" type = "shortstr">
- staging identifier
- <doc>
- This is the staging identifier. This is an arbitrary string chosen
- by the sender. For staging to work correctly the sender must use
- the same staging identifier when staging the same message a second
- time after recovery from a failure. A good choice for the staging
- identifier would be the SHA1 hash of the message properties data
- (including the original filename, revised time, etc.).
- </doc>
- </field>
-
- <field name = "content size" type = "longlong">
- message content size
- <doc>
- The size of the content in octets. The recipient may use this
- information to allocate or check available space in advance, to
- avoid "disk full" errors during staging of very large messages.
- </doc>
- <doc name = "rule">
- The sender MUST accurately fill the content-size field.
- Zero-length content is permitted.
- </doc>
- </field>
-</method>
-
-<method name = "open-ok" synchronous = "1" index = "41">
- confirm staging ready
- <doc>
- This method confirms that the recipient is ready to accept staged
- data. If the message was already partially-staged at a previous
- time the recipient will report the number of octets already staged.
- </doc>
- <response name = "stage" />
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <field name = "staged size" type = "longlong">
- already staged amount
- <doc>
- The amount of previously-staged content in octets. For a new
- message this will be zero.
- </doc>
- <doc name = "rule">
- The sender MUST start sending data from this octet offset in the
- message, counting from zero.
- </doc>
- <doc name = "rule">
- The recipient MAY decide how long to hold partially-staged content
- and MAY implement staging by always discarding partially-staged
- content. However if it uses the file content type it MUST support
- the staging methods.
- </doc>
- </field>
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "stage" content = "1" index = "50">
- stage message content
- <doc>
- This method stages the message, sending the message content to the
- recipient from the octet offset specified in the Open-Ok method.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "publish" index = "60">
- publish a message
- <doc>
- This method publishes a staged file message to a specific exchange.
- The file message will be routed to queues as defined by the exchange
- configuration and distributed to any active consumers when the
- transaction, if any, is committed.
- </doc>
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "write"
- access rights to the access realm for the exchange.
- </doc>
- </field>
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange
- name can be empty, meaning the default exchange. If the exchange
- name is specified, and that exchange does not exist, the server
- will raise a channel exception.
- </doc>
- <doc name = "rule">
- The server MUST accept a blank exchange name to mean the default
- exchange.
- </doc>
- <doc name = "rule">
- If the exchange was declared as an internal exchange, the server
- MUST respond with a reply code 403 (access refused) and raise a
- channel exception.
- </doc>
- <doc name = "rule">
- The exchange MAY refuse file content in which case it MUST respond
- with a reply code 540 (not implemented) and raise a channel
- exception.
- </doc>
- </field>
-
- <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 = "mandatory" type = "bit">
- indicate mandatory routing
- <doc>
- This flag tells the server how to react if the message cannot be
- routed to a queue. If this flag is set, the server will return an
- unroutable message with a Return method. If this flag is zero, the
- server silently drops the message.
- </doc>
- <doc name = "rule" test = "amq_file_00">
- The server SHOULD implement the mandatory flag.
- </doc>
- </field>
-
- <field name = "immediate" type = "bit">
- request immediate delivery
- <doc>
- This flag tells the server how to react if the message cannot be
- routed to a queue consumer immediately. If this flag is set, the
- server will return an undeliverable message with a Return method.
- If this flag is zero, the server will queue the message, but with
- no guarantee that it will ever be consumed.
- </doc>
- <doc name = "rule" test = "amq_file_00">
- The server SHOULD implement the immediate flag.
- </doc>
- </field>
-
- <field name = "identifier" type = "shortstr">
- staging identifier
- <doc>
- This is the staging identifier of the message to publish. The
- message must have been staged. Note that a client can send the
- Publish method asynchronously without waiting for staging to
- finish.
- </doc>
- </field>
-</method>
-
-<method name = "return" content = "1" index = "70">
- return a failed message
- <doc>
- This method returns an undeliverable message that was published
- with the "immediate" flag set, or an unroutable message published
- with the "mandatory" flag set. The reply code and text provide
- information about the reason that the message was undeliverable.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply code" domain = "reply code" />
- <field name = "reply text" domain = "reply text" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was
- originally published to.
- </doc>
- </field>
-
- <field name = "routing key" type = "shortstr">
- Message routing key
- <doc>
- Specifies the routing key name specified when the message was
- published.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "deliver" index = "80">
- notify the client of a consumer message
- <doc>
- This method delivers a staged file message to the client, via a
- consumer. In the asynchronous message delivery model, the client
- starts a consumer using the Consume method, then the server
- responds with Deliver methods as and when messages arrive for
- that consumer.
- </doc>
- <doc name = "rule">
- The server SHOULD track the number of times a message has been
- delivered to clients and when a message is redelivered a certain
- number of times - e.g. 5 times - without being acknowledged, the
- server SHOULD consider the message to be unprocessable (possibly
- causing client applications to abort), and move the message to a
- dead letter queue.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was originally
- published to.
- </doc>
- </field>
-
- <field name = "routing key" type = "shortstr">
- Message routing key
- <doc>
- Specifies the routing key name specified when the message was
- published.
- </doc>
- </field>
-
- <field name = "identifier" type = "shortstr">
- staging identifier
- <doc>
- This is the staging identifier of the message to deliver. The
- message must have been staged. Note that a server can send the
- Deliver method asynchronously without waiting for staging to
- finish.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "ack" index = "90">
- acknowledge one or more messages
- <doc>
- This method acknowledges one or more messages delivered via the
- Deliver method. The client can ask to confirm a single message or
- a set of messages up to and including a specific message.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "multiple" type = "bit">
- acknowledge multiple messages
- <doc>
- If set to 1, the delivery tag is treated as "up to and including",
- so that the client can acknowledge multiple messages with a single
- method. If set to zero, the delivery tag refers to a single
- message. If the multiple field is 1, and the delivery tag is zero,
- tells the server to acknowledge all outstanding mesages.
- </doc>
- <doc name = "rule">
- The server MUST validate that a non-zero delivery-tag refers to an
- delivered message, and raise a channel exception if this is not the
- case.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "reject" index = "100">
- reject an incoming message
- <doc>
- This method allows a client to reject a message. It can be used to
- return untreatable messages to their original queue. Note that file
- content is staged before delivery, so the client will not use this
- method to interrupt delivery of a large message.
- </doc>
- <doc name = "rule">
- The server SHOULD interpret this method as meaning that the client
- is unable to process the message at this time.
- </doc>
- <doc name = "rule">
- A client MUST NOT use this method as a means of selecting messages
- to process. A rejected message MAY be discarded or dead-lettered,
- not necessarily passed to another client.
- </doc>
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "requeue" type = "bit">
- requeue the message
- <doc>
- If this field is zero, the message will be discarded. If this bit
- is 1, the server will attempt to requeue the message.
- </doc>
- <doc name = "rule">
- The server MUST NOT deliver the message to the same client within
- the context of the current channel. The recommended strategy is
- to attempt to deliver the message to an alternative consumer, and
- if that is not possible, to move the message to a dead-letter
- queue. The server MAY use more sophisticated tracking to hold
- the message on the queue and redeliver it to the same client at
- a later stage.
- </doc>
- </field>
-</method>
-
-</class>
-
- <class name="stream" handler="channel" index="80">
- <!--
-======================================================
-== STREAMING
-======================================================
--->
- work with streaming content
-
-<doc>
- The stream class provides methods that support multimedia streaming.
- The stream class uses the following semantics: one message is one
- packet of data; delivery is unacknowleged and unreliable; the consumer
- can specify quality of service parameters that the server can try to
- adhere to; lower-priority messages may be discarded in favour of high
- priority messages.
-</doc>
-
-<doc name = "grammar">
- stream = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:PUBLISH content
- / S:RETURN
- / S:DELIVER content
-</doc>
-
-<chassis name = "server" implement = "MAY" />
-<chassis name = "client" implement = "MAY" />
-
-<doc name = "rule">
- The server SHOULD discard stream messages on a priority basis if
- the queue size exceeds some configured limit.
-</doc>
-<doc name = "rule">
- The server MUST implement at least 2 priority levels for stream
- messages, where priorities 0-4 and 5-9 are treated as two distinct
- levels. The server MAY implement up to 10 priority levels.
-</doc>
-<doc name = "rule">
- The server MUST implement automatic acknowledgements on stream
- content. That is, as soon as a message is delivered to a client
- via a Deliver method, the server must remove it from the queue.
-</doc>
-
-
-<!-- These are the properties for a Stream content -->
-
-<field name = "content type" type = "shortstr">
- MIME content type
-</field>
-<field name = "content encoding" type = "shortstr">
- MIME content encoding
-</field>
-<field name = "headers" type = "table">
- Message header field table
-</field>
-<field name = "priority" type = "octet">
- The message priority, 0 to 9
-</field>
-<field name = "timestamp" type = "timestamp">
- The message timestamp
-</field>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "qos" synchronous = "1" index = "10">
- specify quality of service
- <doc>
- This method requests a specific quality of service. The QoS can
- be specified for the current channel or for all channels on the
- connection. The particular properties and semantics of a qos method
- always depend on the content class semantics. Though the qos method
- could in principle apply to both peers, it is currently meaningful
- only for the server.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "qos-ok" />
-
- <field name = "prefetch size" type = "long">
- prefetch window in octets
- <doc>
- The client can request that messages be sent in advance so that
- when the client finishes processing a message, the following
- message is already held locally, rather than needing to be sent
- down the channel. Prefetching gives a performance improvement.
- This field specifies the prefetch window size in octets. May be
- set to zero, meaning "no specific limit". Note that other
- prefetch limits may still apply.
- </doc>
- </field>
-
- <field name = "prefetch count" type = "short">
- prefetch window in messages
- <doc>
- Specifies a prefetch window in terms of whole messages. This
- field may be used in combination with the prefetch-size field;
- a message will only be sent in advance if both prefetch windows
- (and those at the channel and connection level) allow it.
- </doc>
- </field>
-
- <field name = "consume rate" type = "long">
- transfer rate in octets/second
- <doc>
- Specifies a desired transfer rate in octets per second. This is
- usually determined by the application that uses the streaming
- data. A value of zero means "no limit", i.e. as rapidly as
- possible.
- </doc>
- <doc name = "rule">
- The server MAY ignore the prefetch values and consume rates,
- depending on the type of stream and the ability of the server
- to queue and/or reply it. The server MAY drop low-priority
- messages in favour of high-priority messages.
- </doc>
- </field>
-
- <field name = "global" type = "bit">
- apply to entire connection
- <doc>
- By default the QoS settings apply to the current channel only. If
- this field is set, they are applied to the entire connection.
- </doc>
- </field>
-</method>
-
-<method name = "qos-ok" synchronous = "1" index = "11">
- confirm the requested qos
- <doc>
- This method tells the client that the requested QoS levels could
- be handled by the server. The requested QoS applies to all active
- consumers until a new QoS is defined.
- </doc>
- <chassis name = "client" implement = "MUST" />
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "consume" synchronous = "1" index = "20">
- start a queue consumer
- <doc>
- This method asks the server to start a "consumer", which is a
- transient request for messages from a specific queue. Consumers
- last as long as the channel they were created on, or until the
- client cancels them.
- </doc>
- <doc name = "rule">
- The server SHOULD support at least 16 consumers per queue, unless
- the queue was declared as private, and ideally, impose no limit
- except as defined by available resources.
- </doc>
- <doc name = "rule">
- Streaming applications SHOULD use different channels to select
- different streaming resolutions. AMQP makes no provision for
- filtering and/or transforming streams except on the basis of
- priority-based selective delivery of individual messages.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "read" access
- rights to the realm for the queue.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name
- is null, refers to the current queue for the channel, which is the
- last declared queue.
- </doc>
- <doc name = "rule">
- If the client did not previously declare a queue, and the queue name
- in this method is empty, the server MUST raise a connection exception
- with reply code 530 (not allowed).
- </doc>
- </field>
-
- <field name = "consumer tag" domain = "consumer tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is
- local to a connection, so two clients can use the same consumer
- tags. If this field is empty the server will generate a unique
- tag.
- </doc>
- <doc name = "rule" test = "todo">
- The tag MUST NOT refer to an existing consumer. If the client
- attempts to create two consumers with the same non-empty tag
- the server MUST raise a connection exception with reply code
- 530 (not allowed).
- </doc>
- </field>
-
- <field name = "no local" domain = "no local" />
-
- <field name = "exclusive" type = "bit">
- request exclusive access
- <doc>
- Request exclusive consumer access, meaning only this consumer can
- access the queue.
- </doc>
- <doc name = "rule" test = "amq_file_00">
- If the server cannot grant exclusive access to the queue when asked,
- - because there are other consumers active - it MUST raise a channel
- exception with return code 405 (resource locked).
- </doc>
- </field>
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-</method>
-
-
-<method name = "consume-ok" synchronous = "1" index = "21">
- confirm a new consumer
- <doc>
- This method provides the client with a consumer tag which it may
- use in methods that work with the consumer.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag">
- <doc>
- Holds the consumer tag specified by the client or provided by
- the server.
- </doc>
- </field>
-</method>
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "cancel" synchronous = "1" index = "30">
- end a queue consumer
- <doc>
- This method cancels a consumer. Since message delivery is
- asynchronous the client may continue to receive messages for
- a short while after canceling a consumer. It may process or
- discard these as appropriate.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "cancel-ok" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-
- <field name = "nowait" type = "bit">
- do not send a reply method
- <doc>
- If set, the server will not respond to the method. The client should
- not wait for a reply method. If the server could not complete the
- method it will raise a channel or connection exception.
- </doc>
- </field>
-</method>
-
-<method name = "cancel-ok" synchronous = "1" index = "31">
- confirm a cancelled consumer
- <doc>
- This method confirms that the cancellation was completed.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "publish" content = "1" index = "40">
- publish a message
- <doc>
- This method publishes a message to a specific exchange. The message
- will be routed to queues as defined by the exchange configuration
- and distributed to any active consumers as appropriate.
- </doc>
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access ticket">
- <doc name = "rule">
- The client MUST provide a valid access ticket giving "write"
- access rights to the access realm for the exchange.
- </doc>
- </field>
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange
- name can be empty, meaning the default exchange. If the exchange
- name is specified, and that exchange does not exist, the server
- will raise a channel exception.
- </doc>
- <doc name = "rule">
- The server MUST accept a blank exchange name to mean the default
- exchange.
- </doc>
- <doc name = "rule">
- If the exchange was declared as an internal exchange, the server
- MUST respond with a reply code 403 (access refused) and raise a
- channel exception.
- </doc>
- <doc name = "rule">
- The exchange MAY refuse stream content in which case it MUST
- respond with a reply code 540 (not implemented) and raise a
- channel exception.
- </doc>
- </field>
-
- <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 = "mandatory" type = "bit">
- indicate mandatory routing
- <doc>
- This flag tells the server how to react if the message cannot be
- routed to a queue. If this flag is set, the server will return an
- unroutable message with a Return method. If this flag is zero, the
- server silently drops the message.
- </doc>
- <doc name = "rule" test = "amq_stream_00">
- The server SHOULD implement the mandatory flag.
- </doc>
- </field>
-
- <field name = "immediate" type = "bit">
- request immediate delivery
- <doc>
- This flag tells the server how to react if the message cannot be
- routed to a queue consumer immediately. If this flag is set, the
- server will return an undeliverable message with a Return method.
- If this flag is zero, the server will queue the message, but with
- no guarantee that it will ever be consumed.
- </doc>
- <doc name = "rule" test = "amq_stream_00">
- The server SHOULD implement the immediate flag.
- </doc>
- </field>
-</method>
-
-<method name = "return" content = "1" index = "50">
- return a failed message
- <doc>
- This method returns an undeliverable message that was published
- with the "immediate" flag set, or an unroutable message published
- with the "mandatory" flag set. The reply code and text provide
- information about the reason that the message was undeliverable.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply code" domain = "reply code" />
- <field name = "reply text" domain = "reply text" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was
- originally published to.
- </doc>
- </field>
-
- <field name = "routing key" type = "shortstr">
- Message routing key
- <doc>
- Specifies the routing key name specified when the message was
- published.
- </doc>
- </field>
-</method>
-
-
-<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
-<method name = "deliver" content = "1" index = "60">
- notify the client of a consumer message
- <doc>
- This method delivers a message to the client, via a consumer. In
- the asynchronous message delivery model, the client starts a
- consumer using the Consume method, then the server responds with
- Deliver methods as and when messages arrive for that consumer.
- </doc>
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer tag" domain = "consumer tag" />
-
- <field name = "delivery tag" domain = "delivery tag" />
-
- <field name = "exchange" domain = "exchange name">
- <doc>
- Specifies the name of the exchange that the message was originally
- published to.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue name">
- <doc>
- Specifies the name of the queue that the message came from. Note
- that a single channel can start many consumers on different
- queues.
- </doc>
- <assert check = "notnull" />
- </field>
-</method>
- </class>
-
- <class name="tx" handler="channel" index="90">
- <!--
-======================================================
-== TRANSACTIONS
-======================================================
--->
- work with standard transactions
-
-<doc>
- Standard transactions provide so-called "1.5 phase commit". We can
- ensure that work is never lost, but there is a chance of confirmations
- being lost, so that messages may be resent. Applications that use
- standard transactions must be able to detect and ignore duplicate
- messages.
-</doc>
- <rule implement="SHOULD">
- An client using standard transactions SHOULD be able to track all
- messages received within a reasonable period, and thus detect and
- reject duplicates of the same message. It SHOULD NOT pass these to
- the application layer.
-</rule>
- <doc name="grammar">
- tx = C:SELECT S:SELECT-OK
- / C:COMMIT S:COMMIT-OK
- / C:ROLLBACK S:ROLLBACK-OK
-</doc>
- <chassis name="server" implement="SHOULD"/>
- <chassis name="client" implement="MAY"/>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="select" synchronous="1" index="10">
-select standard transaction mode
- <doc>
- This method sets the channel to use standard transactions. The
- client must use this method at least once on a channel before
- using the Commit or Rollback methods.
- </doc>
- <chassis name="server" implement="MUST"/>
- <response name="select-ok"/>
- </method>
- <method name="select-ok" synchronous="1" index="11">
-confirm transaction mode
- <doc>
- This method confirms to the client that the channel was successfully
- set to use standard transactions.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="commit" synchronous="1" index="20">
-commit the current transaction
- <doc>
- This method commits all messages published and acknowledged in
- the current transaction. A new transaction starts immediately
- after a commit.
- </doc>
- <chassis name="server" implement="MUST"/>
- <response name="commit-ok"/>
- </method>
- <method name="commit-ok" synchronous="1" index="21">
-confirm a successful commit
- <doc>
- This method confirms to the client that the commit succeeded.
- Note that if a commit fails, the server raises a channel exception.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="rollback" synchronous="1" index="30">
-abandon the current transaction
- <doc>
- This method abandons all messages published and acknowledged in
- the current transaction. A new transaction starts immediately
- after a rollback.
- </doc>
- <chassis name="server" implement="MUST"/>
- <response name="rollback-ok"/>
- </method>
- <method name="rollback-ok" synchronous="1" index="31">
-confirm a successful rollback
- <doc>
- This method confirms to the client that the rollback succeeded.
- Note that if an rollback fails, the server raises a channel exception.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- </class>
- <class name="dtx" handler="channel" index="100">
- <!--
-======================================================
-== DISTRIBUTED TRANSACTIONS
-======================================================
--->
- work with distributed transactions
-
-<doc>
- Distributed transactions provide so-called "2-phase commit". The
- AMQP distributed transaction model supports the X-Open XA
- architecture and other distributed transaction implementations.
- The Dtx class assumes that the server has a private communications
- channel (not AMQP) to a distributed transaction coordinator.
-</doc>
- <doc name="grammar">
- dtx = C:SELECT S:SELECT-OK
- C:START S:START-OK
-</doc>
- <chassis name="server" implement="MAY"/>
- <chassis name="client" implement="MAY"/>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="select" synchronous="1" index="10">
-select standard transaction mode
- <doc>
- This method sets the channel to use distributed transactions. The
- client must use this method at least once on a channel before
- using the Start method.
- </doc>
- <chassis name="server" implement="MUST"/>
- <response name="select-ok"/>
- </method>
- <method name="select-ok" synchronous="1" index="11">
-confirm transaction mode
- <doc>
- This method confirms to the client that the channel was successfully
- set to use distributed transactions.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="start" synchronous="1" index="20">
- start a new distributed transaction
- <doc>
- This method starts a new distributed transaction. This must be
- the first method on a new channel that uses the distributed
- transaction mode, before any methods that publish or consume
- messages.
- </doc>
- <chassis name="server" implement="MAY"/>
- <response name="start-ok"/>
- <field name="dtx identifier" type="shortstr">
- transaction identifier
- <doc>
- The distributed transaction key. This identifies the transaction
- so that the AMQP server can coordinate with the distributed
- transaction coordinator.
- </doc>
- <assert check="notnull"/>
- </field>
- </method>
- <method name="start-ok" synchronous="1" index="21">
- confirm the start of a new distributed transaction
- <doc>
- This method confirms to the client that the transaction started.
- Note that if a start fails, the server raises a channel exception.
- </doc>
- <chassis name="client" implement="MUST"/>
- </method>
- </class>
- <class name="tunnel" handler="tunnel" index="110">
- <!--
-======================================================
-== TUNNEL
-======================================================
--->
- methods for protocol tunneling.
-
-<doc>
- The tunnel methods are used to send blocks of binary data - which
- can be serialised AMQP methods or other protocol frames - between
- AMQP peers.
-</doc>
- <doc name="grammar">
- tunnel = C:REQUEST
- / S:REQUEST
-</doc>
- <chassis name="server" implement="MAY"/>
- <chassis name="client" implement="MAY"/>
- <field name="headers" type="table">
- Message header field table
-</field>
- <field name="proxy name" type="shortstr">
- The identity of the tunnelling proxy
-</field>
- <field name="data name" type="shortstr">
- The name or type of the message being tunnelled
-</field>
- <field name="durable" type="octet">
- The message durability indicator
-</field>
- <field name="broadcast" type="octet">
- The message broadcast mode
-</field>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="request" content="1" index="10">
- sends a tunnelled method
- <doc>
- This method tunnels a block of binary data, which can be an
- encoded AMQP method or other data. The binary data is sent
- as the content for the Tunnel.Request method.
- </doc>
- <chassis name="server" implement="MUST"/>
- <field name="meta data" type="table">
- meta data for the tunnelled block
- <doc>
- This field table holds arbitrary meta-data that the sender needs
- to pass to the recipient.
- </doc>
- </field>
- </method>
- </class>
- <class name="test" handler="channel" index="120">
- <!--
-======================================================
-== TEST - CHECK FUNCTIONAL CAPABILITIES OF AN IMPLEMENTATION
-======================================================
--->
- test functional primitives of the implementation
-
-<doc>
- The test class provides methods for a peer to test the basic
- operational correctness of another peer. The test methods are
- intended to ensure that all peers respect at least the basic
- elements of the protocol, such as frame and content organisation
- and field types. We assume that a specially-designed peer, a
- "monitor client" would perform such tests.
-</doc>
- <doc name="grammar">
- test = C:INTEGER S:INTEGER-OK
- / S:INTEGER C:INTEGER-OK
- / C:STRING S:STRING-OK
- / S:STRING C:STRING-OK
- / C:TABLE S:TABLE-OK
- / S:TABLE C:TABLE-OK
- / C:CONTENT S:CONTENT-OK
- / S:CONTENT C:CONTENT-OK
-</doc>
- <chassis name="server" implement="MUST"/>
- <chassis name="client" implement="SHOULD"/>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="integer" synchronous="1" index="10">
- test integer handling
- <doc>
- This method tests the peer's capability to correctly marshal integer
- data.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <response name="integer-ok"/>
- <field name="integer 1" type="octet">
- octet test value
- <doc>
- An octet integer test value.
- </doc>
- </field>
- <field name="integer 2" type="short">
- short test value
- <doc>
- A short integer test value.
- </doc>
- </field>
- <field name="integer 3" type="long">
- long test value
- <doc>
- A long integer test value.
- </doc>
- </field>
- <field name="integer 4" type="longlong">
- long-long test value
- <doc>
- A long long integer test value.
- </doc>
- </field>
- <field name="operation" type="octet">
- operation to test
- <doc>
- The client must execute this operation on the provided integer
- test fields and return the result.
- </doc>
- <assert check="enum">
- <value name="add">return sum of test values</value>
- <value name="min">return lowest of test values</value>
- <value name="max">return highest of test values</value>
- </assert>
- </field>
- </method>
- <method name="integer-ok" synchronous="1" index="11">
- report integer test result
- <doc>
- This method reports the result of an Integer method.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <field name="result" type="longlong">
- result value
- <doc>
- The result of the tested operation.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="string" synchronous="1" index="20">
- test string handling
- <doc>
- This method tests the peer's capability to correctly marshal string
- data.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <response name="string-ok"/>
- <field name="string 1" type="shortstr">
- short string test value
- <doc>
- An short string test value.
- </doc>
- </field>
- <field name="string 2" type="longstr">
- long string test value
- <doc>
- A long string test value.
- </doc>
- </field>
- <field name="operation" type="octet">
- operation to test
- <doc>
- The client must execute this operation on the provided string
- test fields and return the result.
- </doc>
- <assert check="enum">
- <value name="add">return concatentation of test strings</value>
- <value name="min">return shortest of test strings</value>
- <value name="max">return longest of test strings</value>
- </assert>
- </field>
- </method>
- <method name="string-ok" synchronous="1" index="21">
- report string test result
- <doc>
- This method reports the result of a String method.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <field name="result" type="longstr">
- result value
- <doc>
- The result of the tested operation.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="table" synchronous="1" index="30">
- test field table handling
- <doc>
- This method tests the peer's capability to correctly marshal field
- table data.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <response name="table-ok"/>
- <field name="table" type="table">
- field table of test values
- <doc>
- A field table of test values.
- </doc>
- </field>
- <field name="integer op" type="octet">
- operation to test on integers
- <doc>
- The client must execute this operation on the provided field
- table integer values and return the result.
- </doc>
- <assert check="enum">
- <value name="add">return sum of numeric field values</value>
- <value name="min">return min of numeric field values</value>
- <value name="max">return max of numeric field values</value>
- </assert>
- </field>
- <field name="string op" type="octet">
- operation to test on strings
- <doc>
- The client must execute this operation on the provided field
- table string values and return the result.
- </doc>
- <assert check="enum">
- <value name="add">return concatenation of string field values</value>
- <value name="min">return shortest of string field values</value>
- <value name="max">return longest of string field values</value>
- </assert>
- </field>
- </method>
- <method name="table-ok" synchronous="1" index="31">
- report table test result
- <doc>
- This method reports the result of a Table method.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <field name="integer result" type="longlong">
- integer result value
- <doc>
- The result of the tested integer operation.
- </doc>
- </field>
- <field name="string result" type="longstr">
- string result value
- <doc>
- The result of the tested string operation.
- </doc>
- </field>
- </method>
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <method name="content" synchronous="1" content="1" index="40">
- test content handling
- <doc>
- This method tests the peer's capability to correctly marshal content.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <response name="content-ok"/>
- </method>
- <method name="content-ok" synchronous="1" content="1" index="41">
- report content test result
- <doc>
- This method reports the result of a Content method. It contains the
- content checksum and echoes the original content as provided.
- </doc>
- <chassis name="client" implement="MUST"/>
- <chassis name="server" implement="MUST"/>
- <field name="content checksum" type="long">
- content hash
- <doc>
- The 32-bit checksum of the content, calculated by adding the
- content into a 32-bit accumulator.
- </doc>
- </field>
- </method>
- </class>
-</amqp>
diff --git a/gentools/xml-src/amqp-0.9.test.xml b/gentools/xml-src/amqp-0.9.test.xml
deleted file mode 100644
index e12e9c787a..0000000000
--- a/gentools/xml-src/amqp-0.9.test.xml
+++ /dev/null
@@ -1,4282 +0,0 @@
-<?xml version = "1.0"?>
-
-<!--
- EDITORS: (PH) Pieter Hintjens <ph@imatix.com>
- (KvdR) Kim van der Riet <kim.vdriet@redhat.com>
-
- These editors have been assigned by the AMQP working group.
- Please do not edit/commit this file without consulting with
- one of the above editors.
- ========================================================
-
- TODOs
- - see TODO comments in the text
--->
-
-<!--
- Copyright Notice
- ================
- (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc.,
- iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc.,
- TWIST Process Innovations, and 29West Inc. 2006. All rights reserved.
-
- License
- =======
- JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix
- Corporation, IONA\ufffd Technologies, Red Hat, Inc., TWIST Process Innovations, and
- 29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide,
- perpetual, royalty-free, nontransferable, nonexclusive license to
- (i) copy, display, and implement the Advanced Messaging Queue Protocol
- ("AMQP") Specification and (ii) the Licensed Claims that are held by
- the Authors, all for the purpose of implementing the Advanced Messaging
- Queue Protocol Specification. Your license and any rights under this
- Agreement will terminate immediately without notice from
- any Author if you bring any claim, suit, demand, or action related to
- the Advanced Messaging Queue Protocol Specification against any Author.
- Upon termination, you shall destroy all copies of the Advanced Messaging
- Queue Protocol Specification in your possession or control.
-
- As used hereunder, "Licensed Claims" means those claims of a patent or
- patent application, throughout the world, excluding design patents and
- design registrations, owned or controlled, or that can be sublicensed
- without fee and in compliance with the requirements of this
- Agreement, by an Author or its affiliates now or at any
- future time and which would necessarily be infringed by implementation
- of the Advanced Messaging Queue Protocol Specification. A claim is
- necessarily infringed hereunder only when it is not possible to avoid
- infringing it because there is no plausible non-infringing alternative
- for implementing the required portions of the Advanced Messaging Queue
- Protocol Specification. Notwithstanding the foregoing, Licensed Claims
- shall not include any claims other than as set forth above even if
- contained in the same patent as Licensed Claims; or that read solely
- on any implementations of any portion of the Advanced Messaging Queue
- Protocol Specification that are not required by the Advanced Messaging
- Queue Protocol Specification, or that, if licensed, would require a
- payment of royalties by the licensor to unaffiliated third parties.
- Moreover, Licensed Claims shall not include (i) any enabling technologies
- that may be necessary to make or use any Licensed Product but are not
- themselves expressly set forth in the Advanced Messaging Queue Protocol
- Specification (e.g., semiconductor manufacturing technology, compiler
- technology, object oriented technology, networking technology, operating
- system technology, and the like); or (ii) the implementation of other
- published standards developed elsewhere and merely referred to in the
- body of the Advanced Messaging Queue Protocol Specification, or
- (iii) any Licensed Product and any combinations thereof the purpose or
- function of which is not required for compliance with the Advanced
- Messaging Queue Protocol Specification. For purposes of this definition,
- the Advanced Messaging Queue Protocol Specification shall be deemed to
- include both architectural and interconnection requirements essential
- for interoperability and may also include supporting source code artifacts
- where such architectural, interconnection requirements and source code
- artifacts are expressly identified as being required or documentation to
- achieve compliance with the Advanced Messaging Queue Protocol Specification.
-
- As used hereunder, "Licensed Products" means only those specific portions
- of products (hardware, software or combinations thereof) that implement
- and are compliant with all relevant portions of the Advanced Messaging
- Queue Protocol Specification.
-
- The following disclaimers, which you hereby also acknowledge as to any
- use you may make of the Advanced Messaging Queue Protocol Specification:
-
- THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS,"
- AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
- IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE
- CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE
- SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED
- MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY
- PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
-
- THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL,
- INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY
- USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE
- PROTOCOL SPECIFICATION.
-
- The name and trademarks of the Authors may NOT be used in any manner,
- including advertising or publicity pertaining to the Advanced Messaging
- Queue Protocol Specification or its contents without specific, written
- prior permission. Title to copyright in the Advanced Messaging Queue
- Protocol Specification will at all times remain with the Authors.
-
- No other rights are granted by implication, estoppel or otherwise.
-
- Upon termination of your license or rights under this Agreement, you
- shall destroy all copies of the Advanced Messaging Queue Protocol
- Specification in your possession or control.
-
- Trademarks
- ==========
- "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the
- Octagon Symbol are trademarks of JPMorgan Chase & Co.
-
- IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl.
-
- IONA, IONA Technologies, and the IONA logos are trademarks of IONA
- Technologies PLC and/or its subsidiaries.
-
- LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered
- trademarks of Red Hat, Inc. in the US and other countries.
-
- Java, all Java-based trademarks and OpenOffice.org are trademarks of
- Sun Microsystems, Inc. in the United States, other countries, or both.
-
- Other company, product, or service names may be trademarks or service
- marks of others.
-
- Links to full AMQP specification:
- =================================
- http://www.envoytech.org/spec/amq/
- http://www.iona.com/opensource/amqp/
- http://www.redhat.com/solutions/specifications/amqp/
- http://www.twiststandards.org/tiki-index.php?page=AMQ
- http://www.imatix.com/amqp
--->
-
-<!--
- <!DOCTYPE amqp SYSTEM "amqp.dtd">
--->
-
-<!-- XML Notes
-
- We use entities to indicate repetition; attributes to indicate properties.
-
- We use the 'name' attribute as an identifier, usually within the context
- of the surrounding entities.
-
- We use spaces to seperate words in names, so that we can print names in
- their natural form depending on the context - underlines for source code,
- hyphens for written text, etc.
-
- We do not enforce any particular validation mechanism but we support all
- mechanisms. The protocol definition conforms to a formal grammar that is
- published seperately in several technologies.
-
- -->
-
-<amqp major = "0" minor = "9" port = "5672" comment = "AMQ Protocol">
- <!--
- ======================================================
- == CONSTANTS
- ======================================================
- -->
- <!-- Frame types -->
- <constant name = "frame-method" value = "1" />
- <constant name = "frame-header" value = "2" />
- <constant name = "frame-body" value = "3" />
- <constant name = "frame-oob-method" value = "4" />
- <constant name = "frame-oob-header" value = "5" />
- <constant name = "frame-oob-body" value = "6" />
- <constant name = "frame-trace" value = "7" />
- <constant name = "frame-heartbeat" value = "8" />
-
- <!-- Protocol constants -->
- <constant name = "frame-min-size" value = "4096" />
- <constant name = "frame-end" value = "206" />
-
- <!-- Reply codes -->
- <constant name = "reply-success" value = "200">
- <doc>
- Indicates that the method completed successfully. This reply code is
- reserved for future use - the current protocol design does not use positive
- confirmation and reply codes are sent only in case of an error.
- </doc>
- </constant>
-
- <constant name = "not-delivered" value = "310" class = "soft-error">
- <doc>
- The client asked for a specific message that is no longer available.
- The message was delivered to another client, or was purged from the queue
- for some other reason.
- </doc>
- </constant>
-
- <constant name = "content-too-large" value = "311" class = "soft-error">
- <doc>
- The client attempted to transfer content larger than the server could accept
- at the present time. The client may retry at a later time.
- </doc>
- </constant>
-
- <constant name = "connection-forced" value = "320" class = "hard-error">
- <doc>
- An operator intervened to close the connection for some reason. The client
- may retry at some later date.
- </doc>
- </constant>
-
- <constant name = "invalid-path" value = "402" class = "hard-error">
- <doc>
- The client tried to work with an unknown virtual host.
- </doc>
- </constant>
-
- <constant name = "access-refused" value = "403" class = "soft-error">
- <doc>
- The client attempted to work with a server entity to which it has no
- access due to security settings.
- </doc>
- </constant>
-
- <constant name = "not-found" value = "404" class = "soft-error">
- <doc>The client attempted to work with a server entity that does not exist.</doc>
- </constant>
-
- <constant name = "resource-locked" value = "405" class = "soft-error">
- <doc>
- The client attempted to work with a server entity to which it has no
- access because another client is working with it.
- </doc>
- </constant>
-
- <constant name = "precondition-failed" value = "406" class = "soft-error">
- <doc>
- The client requested a method that was not allowed because some precondition
- failed.
- </doc>
- </constant>
-
- <constant name = "frame-error" value = "501" class = "hard-error">
- <doc>
- The client sent a malformed frame that the server could not decode. This
- strongly implies a programming error in the client.
- </doc>
- </constant>
-
- <constant name = "syntax-error" value = "502" class = "hard-error">
- <doc>
- The client sent a frame that contained illegal values for one or more
- fields. This strongly implies a programming error in the client.
- </doc>
- </constant>
-
- <constant name = "command-invalid" value = "503" class = "hard-error">
- <doc>
- The client sent an invalid sequence of frames, attempting to perform an
- operation that was considered invalid by the server. This usually implies
- a programming error in the client.
- </doc>
- </constant>
-
- <constant name = "channel-error" value = "504" class = "hard-error">
- <doc>
- The client attempted to work with a channel that had not been correctly
- opened. This most likely indicates a fault in the client layer.
- </doc>
- </constant>
-
- <constant name = "resource-error" value = "506" class = "hard-error">
- <doc>
- The server could not complete the method because it lacked sufficient
- resources. This may be due to the client creating too many of some type
- of entity.
- </doc>
- </constant>
-
- <constant name = "not-allowed" value = "530" class = "hard-error">
- <doc>
- The client tried to work with some entity in a manner that is prohibited
- by the server, due to security settings or by some other criteria.
- </doc>
- </constant>
-
- <constant name = "not-implemented" value = "540" class = "hard-error">
- <doc>
- The client tried to use functionality that is not implemented in the
- server.
- </doc>
- </constant>
-
- <constant name = "internal-error" value = "541" class = "hard-error">
- <doc>
- The server could not complete the method because of an internal error.
- The server may require intervention by an operator in order to resume
- normal operations.
- </doc>
- </constant>
-
- <constant name = "test-str2" value = "1.2.3.3"/>
-
- <!--
- ======================================================
- == DOMAIN TYPES
- ======================================================
- -->
-
- <domain name = "access-ticket" type = "short" label = "access ticket granted by server">
- <doc>
- An access ticket granted by the server for a certain set of access rights
- within a specific realm. Access tickets are valid within the channel where
- they were created, and expire when the channel closes.
- </doc>
- <assert check = "ne" value = "0" />
- </domain>
-
- <domain name = "class-id" type = "short" />
-
- <domain name = "consumer-tag" type = "shortstr" label = "consumer tag">
- <doc>
- Identifier for the consumer, valid within the current connection.
- </doc>
- </domain>
-
- <domain name = "delivery-tag" type = "longlong" label = "server-assigned delivery tag">
- <doc>
- The server-assigned and channel-specific delivery tag
- </doc>
- <rule name = "channel-local">
- <doc>
- The delivery tag is valid only within the channel from which the message was
- received. I.e. a client MUST NOT receive a message on one channel and then
- acknowledge it on another.
- </doc>
- </rule>
- <rule name = "non-zero">
- <doc>
- The server MUST NOT use a zero value for delivery tags. Zero is reserved
- for client use, meaning "all messages so far received".
- </doc>
- </rule>
- </domain>
-
- <domain name = "exchange-name" type = "shortstr" label = "exchange name">
- <doc>
- The exchange name is a client-selected string that identifies the exchange for publish
- methods. Exchange names may consist of any mixture of digits, letters, and underscores.
- Exchange names are scoped by the virtual host.
- </doc>
- <assert check = "length" value = "127" />
- </domain>
-
- <domain name = "known-hosts" type = "shortstr" label = "list of known hosts">
- <doc>
- Specifies the list of equivalent or alternative hosts that the server knows about,
- which will normally include the current server itself. Clients can cache this
- information and use it when reconnecting to a server after a failure. This field
- may be empty.
- </doc>
- </domain>
-
- <domain name = "method-id" type = "short" />
-
- <domain name = "no-ack" type = "bit" label = "no acknowledgement needed">
- <doc>
- If this field is set the server does not expect acknowledgments for
- messages. That is, when a message is delivered to the client the server
- automatically and silently acknowledges it on behalf of the client. This
- functionality increases performance but at the cost of reliability.
- Messages can get lost if a client dies before it can deliver them to the
- application.
- </doc>
- </domain>
-
- <domain name = "no-local" type = "bit" label = "do not deliver own messages">
- <doc>
- If the no-local field is set the server will not send messages to the client that
- published them.
- </doc>
- </domain>
-
- <domain name = "path" type = "shortstr">
- <doc>
- Must start with a slash "/" and continue with path names separated by slashes. A path
- name consists of any combination of at least one of [A-Za-z0-9] plus zero or more of
- [.-_+!=:].
- </doc>
-
- <assert check = "notnull" />
- <assert check = "syntax" rule = "path" />
- <assert check = "length" value = "127" />
- </domain>
-
- <domain name = "peer-properties" type = "table">
- <doc>
- This string provides a set of peer properties, used for identification, debugging, and
- general information.
- </doc>
- </domain>
-
- <domain name = "queue-name" type = "shortstr" label = "queue name">
- <doc>
- The queue name identifies the queue within the vhost. Queue names may consist of any
- mixture of digits, letters, and underscores.
- </doc>
- <assert check = "length" value = "127" />
- </domain>
-
- <domain name = "redelivered" type = "bit" label = "message is being redelivered">
- <doc>
- This indicates that the message has been previously delivered to this or
- another client.
- </doc>
- <rule name = "implementation">
- <doc>
- The server SHOULD try to signal redelivered messages when it can. When
- redelivering a message that was not successfully acknowledged, the server
- SHOULD deliver it to the original client if possible.
- </doc>
- <doc type = "scenario">
- Create a shared queue and publish a message to the queue. Consume the
- message using explicit acknowledgements, but do not acknowledge the
- message. Close the connection, reconnect, and consume from the queue
- again. The message should arrive with the redelivered flag set.
- </doc>
- </rule>
- <rule name = "hinting">
- <doc>
- The client MUST NOT rely on the redelivered field but should take it as a
- hint that the message may already have been processed. A fully robust
- client must be able to track duplicate received messages on non-transacted,
- and locally-transacted channels.
- </doc>
- </rule>
- </domain>
-
- <domain name = "reply-code" type = "short" label = "reply code from server">
- <doc>
- The reply code. The AMQ reply codes are defined as constants at the start
- of this formal specification.
- </doc>
- <assert check = "notnull" />
- </domain>
-
- <domain name = "reply-text" type = "shortstr" label = "localised reply text">
- <doc>
- The localised reply text. This text can be logged as an aid to resolving
- issues.
- </doc>
- <assert check = "notnull" />
- </domain>
-
- <!-- Elementary domains -->
- <domain name = "bit" type = "bit" label = "single bit" />
- <domain name = "octet" type = "octet" label = "single octet" />
- <domain name = "short" type = "short" label = "16-bit integer" />
- <domain name = "long" type = "long" label = "32-bit integer" />
- <domain name = "longlong" type = "longlong" label = "64-bit integer" />
- <domain name = "shortstr" type = "shortstr" label = "short string" />
- <domain name = "longstr" type = "longstr" label = "long string" />
- <domain name = "timestamp" type = "timestamp" label = "64-bit timestamp" />
- <domain name = "table" type = "table" label = "field table" />
-
- <!-- == CONNECTION ======================================================= -->
-
- <!-- TODO 0.81 - the 'handler' attribute of methods needs to be reviewed, and if
- no current implementations use it, removed. /PH 2006/07/20
- -->
-
- <class name = "connection" handler = "connection" index = "10" label = "work with socket connections">
- <doc>
- The connection class provides methods for a client to establish a network connection to
- a server, and for both peers to operate the connection thereafter.
- </doc>
-
- <doc type = "grammar">
- connection = open-connection *use-connection close-connection
- open-connection = C:protocol-header
- S:START C:START-OK
- *challenge
- S:TUNE C:TUNE-OK
- C:OPEN S:OPEN-OK | S:REDIRECT
- challenge = S:SECURE C:SECURE-OK
- use-connection = *channel
- close-connection = C:CLOSE S:CLOSE-OK
- / S:CLOSE C:CLOSE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "start" synchronous = "1" index = "10" label = "start connection negotiation">
- <doc>
- This method starts the connection negotiation process by telling the client the
- protocol version that the server proposes, along with a list of security mechanisms
- which the client can use for authentication.
- </doc>
-
- <rule name = "protocol-name">
- <doc>
- If the server cannot support the protocol specified in the protocol header,
- it MUST close the socket connection without sending any response method.
- </doc>
- <doc type = "scenario">
- The client sends a protocol header containing an invalid protocol name.
- The server must respond by closing the connection.
- </doc>
- </rule>
- <rule name = "server-support">
- <doc>
- The server MUST provide a protocol version that is lower than or equal to
- that requested by the client in the protocol header.
- </doc>
- <doc type = "scenario">
- The client requests a protocol version that is higher than any valid
- implementation, e.g. 9.0. The server must respond with a current
- protocol version, e.g. 1.0.
- </doc>
- </rule>
- <rule name = "client-support">
- <doc>
- If the client cannot handle the protocol version suggested by the server
- it MUST close the socket connection.
- </doc>
- <doc type = "scenario">
- The server sends a protocol version that is lower than any valid
- implementation, e.g. 0.1. The client must respond by closing the
- connection.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
- <response name = "start-ok" />
-
- <field name = "version-major" domain = "octet" label = "protocol major version">
- <doc>
- The version of the protocol, expressed in protocol units of 0.1 public
- versions and properly printed as two digits with a leading zero. I.e. a
- protocol version of "09" represents a public version "0.9". The decimal
- shift allows the correct expression of pre-1.0 protocol releases.
- </doc>
- <doc type = "todo">
- This field should be renamed to "protocol version".
- </doc>
- </field>
-
- <field name = "version-minor" domain = "octet" label = "protocol major version">
- <doc>
- The protocol revision, expressed as an integer from 0 to 9. The use of more
- than ten revisions is discouraged. The public version string is constructed
- from the protocol version and revision as follows: we print the protocol
- version with one decimal position, and we append the protocol revision. A
- version=10 and revision=2 are printed as "1.02".
- </doc>
- <doc type = "todo">
- This field should be renamed to "protocol revision".
- </doc>
- </field>
-
- <field name = "server-properties" domain = "peer-properties" label = "server properties">
- <rule name = "required-fields">
- <doc>
- The properties SHOULD contain at least these fields: "host", specifying the
- server host name or address, "product", giving the name of the server product,
- "version", giving the name of the server version, "platform", giving the name
- of the operating system, "copyright", if appropriate, and "information", giving
- other general information.
- </doc>
- <doc type = "scenario">
- Client connects to server and inspects the server properties. It checks for
- the presence of the required fields.
- </doc>
- </rule>
- </field>
-
- <field name = "mechanisms" domain = "longstr" label = "available security mechanisms">
- <doc>
- A list of the security mechanisms that the server supports, delimited by spaces.
- Currently ASL supports these mechanisms: PLAIN.
- </doc>
- <assert check = "notnull" />
- </field>
-
- <field name = "locales" domain = "longstr" label = "available message locales">
- <doc>
- A list of the message locales that the server supports, delimited by spaces. The
- locale defines the language in which the server will send reply texts.
- </doc>
- <rule name = "required-support">
- <doc>
- The server MUST support at least the en_US locale.
- </doc>
- <doc type = "scenario">
- Client connects to server and inspects the locales field. It checks for
- the presence of the required locale(s).
- </doc>
- </rule>
- <assert check = "notnull" />
- </field>
- </method>
-
- <method name = "start-ok" synchronous = "1" index = "11"
- label = "select security mechanism and locale">
- <doc>
- This method selects a SASL security mechanism. ASL uses SASL (RFC2222) to
- negotiate authentication and encryption.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "client-properties" domain = "peer-properties" label = "client properties">
- <rule name = "required-fields">
- <!-- This rule is not testable from the client side -->
- <doc>
- The properties SHOULD contain at least these fields: "product", giving the name
- of the client product, "version", giving the name of the client version, "platform",
- giving the name of the operating system, "copyright", if appropriate, and
- "information", giving other general information.
- </doc>
- </rule>
- </field>
-
- <field name = "mechanism" domain = "shortstr" label = "selected security mechanism">
- <doc>
- A single security mechanisms selected by the client, which must be one of those
- specified by the server.
- </doc>
- <rule name = "security">
- <doc>
- The client SHOULD authenticate using the highest-level security profile it
- can handle from the list provided by the server.
- </doc>
- </rule>
- <rule name = "validity">
- <doc>
- If the mechanism field does not contain one of the security mechanisms
- proposed by the server in the Start method, the server MUST close the
- connection without sending any further data.
- </doc>
- <doc type = "scenario">
- Client connects to server and sends an invalid security mechanism. The
- server must respond by closing the connection (a socket close, with no
- connection close negotiation).
- </doc>
- </rule>
- <assert check = "notnull" />
- </field>
-
- <field name = "response" domain = "longstr" label = "security response data">
- <doc>
- A block of opaque data passed to the security mechanism. The contents of this
- data are defined by the SASL security mechanism.
- </doc>
- <assert check = "notnull" />
- </field>
-
- <field name = "locale" domain = "shortstr" label = "selected message locale">
- <doc>
- A single message local selected by the client, which must be one of those
- specified by the server.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "secure" synchronous = "1" index = "20" label = "security mechanism challenge">
- <doc>
- The SASL protocol works by exchanging challenges and responses until both peers have
- received sufficient information to authenticate each other. This method challenges
- the client to provide more information.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
- <response name = "secure-ok" />
-
- <field name = "challenge" domain = "longstr" label = "security challenge data">
- <doc>
- Challenge information, a block of opaque binary data passed to the security
- mechanism.
- </doc>
- </field>
- </method>
-
- <method name = "secure-ok" synchronous = "1" index = "21" label = "security mechanism response">
- <doc>
- This method attempts to authenticate, passing a block of SASL data for the security
- mechanism at the server side.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "response" domain = "longstr" label = "security response data">
- <doc>
- A block of opaque data passed to the security mechanism. The contents of this
- data are defined by the SASL security mechanism.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "tune" synchronous = "1" index = "30"
- label = "propose connection tuning parameters">
- <doc>
- This method proposes a set of connection configuration values to the client. The
- client can accept and/or adjust these.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <response name = "tune-ok" />
-
- <field name = "channel-max" domain = "short" label = "proposed maximum channels">
- <doc>
- The maximum total number of channels that the server allows per connection. Zero
- means that the server does not impose a fixed limit, but the number of allowed
- channels may be limited by available server resources.
- </doc>
- </field>
-
- <field name = "frame-max" domain = "long" label = "proposed maximum frame size">
- <doc>
- The largest frame size that the server proposes for the connection. The client
- can negotiate a lower value. Zero means that the server does not impose any
- specific limit but may reject very large frames if it cannot allocate resources
- for them.
- </doc>
- <rule name = "minimum">
- <doc>
- Until the frame-max has been negotiated, both peers MUST accept frames of up
- to frame-min-size octets large, and the minimum negotiated value for frame-max
- is also frame-min-size.
- </doc>
- <doc type = "scenario">
- Client connects to server and sends a large properties field, creating a frame
- of frame-min-size octets. The server must accept this frame.
- </doc>
- </rule>
- </field>
-
- <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
- <!-- TODO 0.82 - the heartbeat negotiation mechanism was changed during
- implementation because the model documented here does not actually
- work properly. The best model we found is that the server proposes
- a heartbeat value to the client; the client can reply with zero, meaning
- 'do not use heartbeats (as documented here), or can propose its own
- heartbeat value, which the server should then accept. This is different
- from the model here which is disconnected - e.g. each side requests a
- heartbeat independently. Basically a connection is heartbeated in
- both ways, or not at all, depending on whether both peers support
- heartbeating or not, and the heartbeat value should itself be chosen
- by the client so that remote links can get a higher value. Also, the
- actual heartbeat mechanism needs documentation, and is as follows: so
- long as there is activity on a connection - in or out - both peers
- assume the connection is active. When there is no activity, each peer
- must send heartbeat frames. When no heartbeat frame is received after
- N cycles (where N is at least 2), the connection can be considered to
- have died. /PH 2006/07/19
- -->
- <doc>
- The delay, in seconds, of the connection heartbeat that the server wants.
- Zero means the server does not want a heartbeat.
- </doc>
- </field>
- </method>
-
- <method name = "tune-ok" synchronous = "1" index = "31"
- label = "negotiate connection tuning parameters">
- <doc>
- This method sends the client's connection tuning parameters to the server.
- Certain fields are negotiated, others provide capability information.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "channel-max" domain = "short" label = "negotiated maximum channels">
- <doc>
- The maximum total number of channels that the client will use per connection.
- </doc>
- <rule name = "upper-limit">
- <doc>
- If the client specifies a channel max that is higher than the value provided
- by the server, the server MUST close the connection without attempting a
- negotiated close. The server may report the error in some fashion to assist
- implementors.
- </doc>
- </rule>
- <assert check = "notnull" />
- <assert check = "le" method = "tune" field = "channel-max" />
- </field>
-
- <field name = "frame-max" domain = "long" label = "negotiated maximum frame size">
- <doc>
- The largest frame size that the client and server will use for the connection.
- Zero means that the client does not impose any specific limit but may reject
- very large frames if it cannot allocate resources for them. Note that the
- frame-max limit applies principally to content frames, where large contents can
- be broken into frames of arbitrary size.
- </doc>
- <rule name = "minimum">
- <doc>
- Until the frame-max has been negotiated, both peers MUST accept frames of up
- to frame-min-size octets large, and the minimum negotiated value for frame-max
- is also frame-min-size.
- </doc>
- </rule>
- <rule name = "upper-limit">
- <doc>
- If the client specifies a frame max that is higher than the value provided
- by the server, the server MUST close the connection without attempting a
- negotiated close. The server may report the error in some fashion to assist
- implementors.
- </doc>
- </rule>
- </field>
-
- <field name = "heartbeat" domain = "short" label = "desired heartbeat delay">
- <doc>
- The delay, in seconds, of the connection heartbeat that the client wants. Zero
- means the client does not want a heartbeat.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "open" synchronous = "1" index = "40" label = "open connection to virtual host">
- <doc>
- This method opens a connection to a virtual host, which is a collection of
- resources, and acts to separate multiple application domains within a server.
- The server may apply arbitrary limits per virtual host, such as the number
- of each type of entity that may be used, per connection and/or in total.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "open-ok" />
- <response name = "redirect" />
-
- <field name = "virtual-host" domain = "path" label = "virtual host name">
- <!-- TODO 0.82 - the entire vhost model needs review. This concept was
- prompted by the HTTP vhost concept but does not fit very well into
- AMQP. Currently we use the vhost as a "cluster identifier" which is
- inaccurate usage. /PH 2006/07/19
- -->
- <assert check = "regexp" value = "^[a-zA-Z0-9/-_]+$" />
- <doc>
- The name of the virtual host to work with.
- </doc>
- <rule name = "separation">
- <doc>
- If the server supports multiple virtual hosts, it MUST enforce a full
- separation of exchanges, queues, and all associated entities per virtual
- host. An application, connected to a specific virtual host, MUST NOT be able
- to access resources of another virtual host.
- </doc>
- </rule>
- <rule name = "security">
- <doc>
- The server SHOULD verify that the client has permission to access the
- specified virtual host.
- </doc>
- </rule>
- </field>
-
- <field name = "capabilities" domain = "shortstr" label = "required capabilities">
- <doc>
- The client can specify zero or more capability names, delimited by spaces.
- The server can use this string to how to process the client's connection
- request.
- </doc>
- </field>
-
- <field name = "insist" domain = "bit" label = "insist on connecting to server">
- <doc>
- In a configuration with multiple collaborating servers, the server may respond
- to a Connection.Open method with a Connection.Redirect. The insist option tells
- the server that the client is insisting on a connection to the specified server.
- </doc>
- <rule name = "behaviour">
- <doc>
- When the client uses the insist option, the server MUST NOT respond with a
- Connection.Redirect method. If it cannot accept the client's connection
- request it should respond by closing the connection with a suitable reply
- code.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "open-ok" synchronous = "1" index = "41" label = "signal that connection is ready">
- <doc>
- This method signals to the client that the connection is ready for use.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "known-hosts" domain = "known-hosts" />
- </method>
-
- <method name = "redirect" synchronous = "1" index = "42" label = "redirects client to other server">
- <doc>
- This method redirects the client to another server, based on the requested virtual
- host and/or capabilities.
- </doc>
- <rule name = "usage">
- <doc>
- When getting the Connection.Redirect method, the client SHOULD reconnect to
- the host specified, and if that host is not present, to any of the hosts
- specified in the known-hosts list.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <field name = "host" domain = "shortstr" label = "server to connect to">
- <doc>
- Specifies the server to connect to. This is an IP address or a DNS name,
- optionally followed by a colon and a port number. If no port number is
- specified, the client should use the default port number for the protocol.
- </doc>
- <assert check = "notnull" />
- </field>
- <field name = "known-hosts" domain = "known-hosts" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "close" synchronous = "1" index = "50" label = "request a connection close">
- <doc>
- This method indicates that the sender wants to close the connection. This may be
- due to internal conditions (e.g. a forced shut-down) or due to an error handling
- a specific method, i.e. an exception. When a close is due to an exception, the
- sender provides the class and method id of the method which caused the exception.
- </doc>
- <!-- TODO: the connection close mechanism needs to be reviewed from the ODF
- documentation and better expressed as rules here. /PH 2006/07/20
- -->
- <rule name = "stability">
- <doc>
- After sending this method any received method except the Close-OK method MUST
- be discarded.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- <response name = "close-ok" />
-
- <field name = "reply-code" domain = "reply-code" />
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "class-id" domain = "class-id" label = "failing method class">
- <doc>
- When the close is provoked by a method exception, this is the class of the
- method.
- </doc>
- </field>
-
- <field name = "method-id" domain = "method-id" label = "failing method ID">
- <doc>
- When the close is provoked by a method exception, this is the ID of the method.
- </doc>
- </field>
- </method>
-
- <method name = "close-ok" synchronous = "1" index = "51" label = "confirm a connection close">
- <doc>
- This method confirms a Connection.Close method and tells the recipient that it is
- safe to release resources for the connection and close the socket.
- </doc>
- <rule name = "reporting">
- <doc>
- A peer that detects a socket closure without having received a Close-Ok
- handshake method SHOULD log the error.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- </method>
- </class>
-
- <!-- == CHANNEL ========================================================== -->
-
- <class name = "channel" handler = "channel" index = "20" label = "work with channels">
- <doc>
- The channel class provides methods for a client to establish a channel to a
- server and for both peers to operate the channel thereafter.
- </doc>
-
- <doc type = "grammar">
- channel = open-channel *use-channel close-channel
- open-channel = C:OPEN S:OPEN-OK
- use-channel = C:FLOW S:FLOW-OK
- / S:FLOW C:FLOW-OK
- / S:ALERT
- / functional-class
- close-channel = C:CLOSE S:CLOSE-OK
- / S:CLOSE C:CLOSE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "open" synchronous = "1" index = "10" label = "open a channel for use">
- <doc>
- This method opens a channel to the server.
- </doc>
- <rule name = "state" on-failure = "channel-error">
- <doc>
- The client MUST NOT use this method on an alread-opened channel.
- </doc>
- <doc type = "scenario">
- Client opens a channel and then reopens the same channel.
- </doc>
- </rule>
- <chassis name = "server" implement = "MUST" />
- <response name = "open-ok" />
- <field name = "out of band" domain = "shortstr" label = "out-of-band settings">
- <doc>
- Configures out-of-band transfers on this channel. The syntax and meaning of this
- field will be formally defined at a later date.
- </doc>
- <assert check = "null" />
- </field>
- </method>
-
- <method name = "open-ok" synchronous = "1" index = "11" label = "signal that the channel is ready">
- <doc>
- This method signals to the client that the channel is ready for use.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "flow" synchronous = "1" index = "20" label = "enable/disable flow from peer">
- <doc>
- This method asks the peer to pause or restart the flow of content data. This is a
- simple flow-control mechanism that a peer can use to avoid oveflowing its queues or
- otherwise finding itself receiving more messages than it can process. Note that this
- method is not intended for window control. The peer that receives a disable flow
- method should finish sending the current content frame, if any, then pause.
- </doc>
-
- <rule name = "initial-state">
- <doc>
- When a new channel is opened, it is active (flow is active). Some applications
- assume that channels are inactive until started. To emulate this behaviour a
- client MAY open the channel, then pause it.
- </doc>
- </rule>
-
- <rule name = "bidirectional">
- <doc>
- When sending content frames, a peer SHOULD monitor the channel for incoming
- methods and respond to a Channel.Flow as rapidly as possible.
- </doc>
- </rule>
-
- <rule name = "throttling">
- <doc>
- A peer MAY use the Channel.Flow method to throttle incoming content data for
- internal reasons, for example, when exchanging data over a slower connection.
- </doc>
- </rule>
-
- <rule name = "expected-behaviour">
- <doc>
- The peer that requests a Channel.Flow method MAY disconnect and/or ban a peer
- that does not respect the request. This is to prevent badly-behaved clients
- from overwhelming a broker.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <response name = "flow-ok" />
-
- <field name = "active" domain = "bit" label = "start/stop content frames">
- <doc>
- If 1, the peer starts sending content frames. If 0, the peer stops sending
- content frames.
- </doc>
- </field>
- </method>
-
- <method name = "flow-ok" index = "21" label = "confirm a flow method">
- <doc>
- Confirms to the peer that a flow command was received and processed.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
- <field name = "active" domain = "bit" label = "current flow setting">
- <doc>
- Confirms the setting of the processed flow method: 1 means the peer will start
- sending or continue to send content frames; 0 means it will not.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- TODO 0.82 - remove this method entirely
- /PH 2006/07/20
- -->
- <method name = "alert" index = "30" label = "send a non-fatal warning message">
- <doc>
- This method allows the server to send a non-fatal warning to the client. This is
- used for methods that are normally asynchronous and thus do not have confirmations,
- and for which the server may detect errors that need to be reported. Fatal errors
- are handled as channel or connection exceptions; non-fatal errors are sent through
- this method.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "reply-code" domain = "reply-code" />
- <field name = "reply-text" domain = "reply-text" />
- <field name = "details" domain = "table" label = "detailed information for warning">
- <doc>
- A set of fields that provide more information about the problem. The meaning of
- these fields are defined on a per-reply-code basis (TO BE DEFINED).
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "close" synchronous = "1" index = "40" label = "request a channel close">
- <doc>
- This method indicates that the sender wants to close the channel. This may be due to
- internal conditions (e.g. a forced shut-down) or due to an error handling a specific
- method, i.e. an exception. When a close is due to an exception, the sender provides
- the class and method id of the method which caused the exception.
- </doc>
-
- <!-- TODO: the channel close behaviour needs to be reviewed from the ODF
- documentation and better expressed as rules here. /PH 2006/07/20
- -->
- <rule name = "stability">
- <doc>
- After sending this method any received method except the Close-OK method MUST
- be discarded.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- <response name = "close-ok" />
-
- <field name = "reply-code" domain = "reply-code" />
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "class-id" domain = "class-id" label = "failing method class">
- <doc>
- When the close is provoked by a method exception, this is the class of the
- method.
- </doc>
- </field>
-
- <field name = "method-id" domain = "method-id" label = "failing method ID">
- <doc>
- When the close is provoked by a method exception, this is the ID of the method.
- </doc>
- </field>
- </method>
-
- <method name = "close-ok" synchronous = "1" index = "41" label = "confirm a channel close">
- <doc>
- This method confirms a Channel.Close method and tells the recipient that it is safe
- to release resources for the channel and close the socket.
- </doc>
- <rule name = "reporting">
- <doc>
- A peer that detects a socket closure without having received a Channel.Close-Ok
- handshake method SHOULD log the error.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <chassis name = "server" implement = "MUST" />
- </method>
- </class>
-
- <!-- == ACCESS =========================================================== -->
-
- <!-- TODO 0.82 - this class must be implemented by two teams before we can
- consider it matured.
- -->
-
- <class name = "access" handler = "connection" index = "30" label = "work with access tickets">
- <doc>
- The protocol control access to server resources using access tickets. A
- client must explicitly request access tickets before doing work. An access
- ticket grants a client the right to use a specific set of resources -
- called a "realm" - in specific ways.
- </doc>
-
- <doc type = "grammar">
- access = C:REQUEST S:REQUEST-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "request" synchronous = "1" index = "10" label = "request an access ticket">
- <doc>
- This method requests an access ticket for an access realm. The server
- responds by granting the access ticket. If the client does not have
- access rights to the requested realm this causes a connection exception.
- Access tickets are a per-channel resource.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "request-ok" />
-
- <field name = "realm" domain = "shortstr" label = "name of requested realm">
- <doc>
- Specifies the name of the realm to which the client is requesting access.
- The realm is a configured server-side object that collects a set of
- resources (exchanges, queues, etc.). If the channel has already requested
- an access ticket onto this realm, the previous ticket is destroyed and a
- new ticket is created with the requested access rights, if allowed.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST specify a realm that is known to the server. The server
- makes an identical response for undefined realms as it does for realms
- that are defined but inaccessible to this client.
- </doc>
- <doc type = "scenario">
- Client specifies an undefined realm.
- </doc>
- </rule>
- </field>
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive access to the realm, meaning that this will be the only
- channel that uses the realm's resources.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MAY NOT request exclusive access to a realm that has active
- access tickets, unless the same channel already had the only access
- ticket onto that realm.
- </doc>
- <doc type = "scenario">
- Client opens two channels and requests exclusive access to the same realm.
- </doc>
- </rule>
- </field>
- <field name = "passive" domain = "bit" label = "request passive access">
- <doc>
- Request message passive access to the specified access realm. Passive
- access lets a client get information about resources in the realm but
- not to make any changes to them.
- </doc>
- </field>
- <field name = "active" domain = "bit" label = "request active access">
- <doc>
- Request message active access to the specified access realm. Active access lets
- a client get create and delete resources in the realm.
- </doc>
- </field>
- <field name = "write" domain = "bit" label = "request write access">
- <doc>
- Request write access to the specified access realm. Write access lets a client
- publish messages to all exchanges in the realm.
- </doc>
- </field>
- <field name = "read" domain = "bit" label = "request read access">
- <doc>
- Request read access to the specified access realm. Read access lets a client
- consume messages from queues in the realm.
- </doc>
- </field>
- </method>
-
- <method name = "request-ok" synchronous = "1" index = "11" label = "grant access to server resources">
- <doc>
- This method provides the client with an access ticket. The access ticket is valid
- within the current channel and for the lifespan of the channel.
- </doc>
- <rule name = "per-channel" on-failure = "not-allowed">
- <doc>
- The client MUST NOT use access tickets except within the same channel as
- originally granted.
- </doc>
- <doc type = "scenario">
- Client opens two channels, requests a ticket on one channel, and then
- tries to use that ticket in a seconc channel.
- </doc>
- </rule>
- <chassis name = "client" implement = "MUST" />
- <field name = "ticket" domain = "access-ticket" />
- </method>
- </class>
-
- <!-- == EXCHANGE ========================================================= -->
-
- <class name = "exchange" handler = "channel" index = "40" label = "work with exchanges">
- <doc>
- Exchanges match and distribute messages across queues. Exchanges can be configured in
- the server or created at runtime.
- </doc>
-
- <doc type = "grammar">
- exchange = C:DECLARE S:DECLARE-OK
- / C:DELETE S:DELETE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <rule name = "required-types">
- <doc>
- The server MUST implement these standard exchange types: fanout, direct.
- </doc>
- <doc type = "scenario">
- Client attempts to declare an exchange with each of these standard types.
- </doc>
- </rule>
- <rule name = "recommended-types">
- <doc>
- The server SHOULD implement these standard exchange types: topic, headers.
- </doc>
- <doc type = "scenario">
- Client attempts to declare an exchange with each of these standard types.
- </doc>
- </rule>
- <rule name = "required-instances">
- <doc>
- The server MUST, in each virtual host, pre-declare an exchange instance
- for each standard exchange type that it implements, where the name of the
- exchange instance is "amq." followed by the exchange type name.
- </doc>
- <doc type = "scenario">
- Client creates a temporary queue and attempts to bind to each required
- exchange instance (amq.fanout, amq.direct, and amq.topic, amq.headers if
- those types are defined).
- </doc>
- </rule>
- <rule name = "default-exchange">
- <doc>
- The server MUST predeclare a direct exchange to act as the default exchange
- for content Publish methods and for default queue bindings.
- </doc>
- <doc type = "scenario">
- Client checks that the default exchange is active by specifying a queue
- binding with no exchange name, and publishing a message with a suitable
- routing key but without specifying the exchange name, then ensuring that
- the message arrives in the queue correctly.
- </doc>
- </rule>
- <rule name = "default-access">
- <doc>
- The server MUST NOT allow clients to access the default exchange except
- by specifying an empty exchange name in the Queue.Bind and content Publish
- methods.
- </doc>
- </rule>
- <rule name = "extensions">
- <doc>
- The server MAY implement other exchange types as wanted.
- </doc>
- </rule>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "declare" synchronous = "1" index = "10" label = "declare exchange, create if needed">
- <doc>
- This method creates an exchange if it does not already exist, and if the exchange
- exists, verifies that it is of the correct and expected class.
- </doc>
- <rule name = "minimum">
- <doc>
- The server SHOULD support a minimum of 16 exchanges per virtual host and
- ideally, impose no limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- The client creates as many exchanges as it can until the server reports
- an error; the number of exchanges successfuly created must be at least
- sixteen.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "declare-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- When a client defines a new exchange, this belongs to the access realm of the
- ticket used. All further work done with that exchange must be done with an
- access ticket for the same realm.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "active" access to
- the realm in which the exchange exists or will be created, or "passive"
- access if the if-exists flag is set.
- </doc>
- <doc type = "scenario">
- Client creates access ticket with wrong access rights and attempts to use
- in this method.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <rule name = "reserved" on-failure = "access-refused">
- <doc>
- Exchange names starting with "amq." are reserved for predeclared and
- standardised exchanges. The client MUST NOT attempt to create an exchange
- starting with "amq.".
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" />
- </field>
-
- <field name = "type" domain = "shortstr" label = "exchange type">
- <doc>
- Each exchange belongs to one of a set of exchange types implemented by the
- server. The exchange types define the functionality of the exchange - i.e. how
- messages are routed through it. It is not valid or meaningful to attempt to
- change the type of an existing exchange.
- </doc>
- <rule name = "typed" on-failure = "not-allowed">
- <doc>
- Exchanges cannot be redeclared with different types. The client MUST not
- attempt to redeclare an existing exchange with a different type than used
- in the original Exchange.Declare method.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <rule name = "support" on-failure = "command-invalid">
- <doc>
- The client MUST NOT attempt to create an exchange with a type that the
- server does not support.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" />
- </field>
-
- <field name = "passive" domain = "bit" label = "do not create exchange">
- <doc>
- If set, the server will not create the exchange. The client can use this to
- check whether an exchange exists without modifying the server state.
- </doc>
- <rule name = "not-found">
- <doc>
- If set, and the exchange does not already exist, the server MUST raise a
- channel exception with reply code 404 (not found).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "durable" domain = "bit" label = "request a durable exchange">
- <doc>
- If set when creating a new exchange, the exchange will be marked as durable.
- Durable exchanges remain active when a server restarts. Non-durable exchanges
- (transient exchanges) are purged if/when a server restarts.
- </doc>
- <rule name = "support">
- <doc>
- The server MUST support both durable and transient exchanges.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- <rule name = "sticky">
- <doc>
- The server MUST ignore the durable field if the exchange already exists.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <!-- TODO 0.82 - clarify how this works; there is no way to cancel a binding
- except by deleting a queue.
- -->
- <field name = "auto-delete" domain = "bit" label = "auto-delete when unused">
- <doc>
- If set, the exchange is deleted when all queues have finished using it.
- </doc>
- <rule name = "sticky">
- <doc>
- The server MUST ignore the auto-delete field if the exchange already
- exists.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "internal" domain = "bit" label = "create internal exchange">
- <doc>
- If set, the exchange may not be used directly by publishers, but only when bound
- to other exchanges. Internal exchanges are used to construct wiring that is not
- visible to applications.
- </doc>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
-
- <field name = "arguments" domain = "table" label = "arguments for declaration">
- <doc>
- A set of arguments for the declaration. The syntax and semantics of these
- arguments depends on the server implementation. This field is ignored if passive
- is 1.
- </doc>
- </field>
- </method>
-
- <method name = "declare-ok" synchronous = "1" index = "11" label = "confirm exchange declaration">
- <doc>
- This method confirms a Declare method and confirms the name of the exchange,
- essential for automatically-named exchanges.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "delete" synchronous = "1" index = "20" label = "delete an exchange">
- <doc>
- This method deletes an exchange. When an exchange is deleted all queue bindings on
- the exchange are cancelled.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "delete-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "active" access
- rights to the exchange's access realm.
- </doc>
- <doc type = "scenario">
- Client creates access ticket with wrong access rights and attempts to use
- in this method.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <rule name = "exists" on-failure = "not-found">
- <doc>
- The client MUST NOT attempt to delete an exchange that does not exist.
- </doc>
- </rule>
- <assert check = "notnull" />
- </field>
-
- <!-- TODO 0.82 - discuss whether this option is useful or not. I don't have
- any real use case for it. /PH 2006-07-23.
- -->
- <field name = "if-unused" domain = "bit" label = "delete only if unused">
- <doc>
- If set, the server will only delete the exchange if it has no queue bindings. If
- the exchange has queue bindings the server does not delete it but raises a
- channel exception instead.
- </doc>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "delete-ok" synchronous = "1" index = "21"
- label = "confirm deletion of an exchange">
- <doc>This method confirms the deletion of an exchange.</doc>
- <chassis name = "client" implement = "MUST" />
- </method>
- </class>
-
- <!-- == QUEUE ============================================================ -->
-
- <class name = "queue" handler = "channel" index = "50" label = "work with queues">
- <doc>
- Queues store and forward messages. Queues can be configured in the server or created at
- runtime. Queues must be attached to at least one exchange in order to receive messages
- from publishers.
- </doc>
-
- <doc type = "grammar">
- queue = C:DECLARE S:DECLARE-OK
- / C:BIND S:BIND-OK
- / C:PURGE S:PURGE-OK
- / C:DELETE S:DELETE-OK
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <rule name = "any-content">
- <doc>
- A server MUST allow any content class to be sent to any queue, in any mix, and
- queue and deliver these content classes independently. Note that all methods
- that fetch content off queues are specific to a given content class.
- </doc>
- <doc type = "scenario">
- Client creates an exchange of each standard type and several queues that
- it binds to each exchange. It must then sucessfully send each of the standard
- content types to each of the available queues.
- </doc>
- </rule>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "declare" synchronous = "1" index = "10" label = "declare queue, create if needed">
- <doc>
- This method creates or checks a queue. When creating a new queue the client can
- specify various properties that control the durability of the queue and its
- contents, and the level of sharing for the queue.
- </doc>
-
- <rule name = "default-binding">
- <doc>
- The server MUST create a default binding for a newly-created queue to the
- default exchange, which is an exchange of type 'direct'.
- </doc>
- <doc type = "scenario">
- Client creates a new queue, and then without explicitly binding it to an
- exchange, attempts to send a message through the default exchange binding,
- i.e. publish a message to the empty exchange, with the queue name as routing
- key.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_35" -->
- <rule name = "minimum-queues">
- <doc>
- The server SHOULD support a minimum of 256 queues per virtual host and ideally,
- impose no limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- Client attempts to create as many queues as it can until the server reports
- an error. The resulting count must at least be 256.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "declare-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- When a client defines a new queue, this belongs to the access realm of the
- ticket used. All further work done with that queue must be done with an access
- ticket for the same realm.
- </doc>
- <rule name = "validity" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "active" access to
- the realm in which the queue exists or will be created.
- </doc>
- <doc type = "scenario">
- Client creates access ticket with wrong access rights and attempts to use
- in this method.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <rule name = "default-name">
- <doc>
- The queue name MAY be empty, in which case the server MUST create a new
- queue with a unique generated name and return this to the client in the
- Declare-Ok method.
- </doc>
- <doc type = "scenario">
- Client attempts to create several queues with an empty name. The client then
- verifies that the server-assigned names are unique and different.
- </doc>
- </rule>
- <rule name = "reserved-prefix" on-failure = "not-allowed">
- <doc>
- Queue names starting with "amq." are reserved for predeclared and
- standardised server queues. A client MAY NOT attempt to declare a queue with a
- name that starts with "amq." and the passive option set to zero.
- </doc>
- <doc type = "scenario">
- A client attempts to create a queue with a name starting with "amq." and with
- the passive option set to zero.
- </doc>
- </rule>
- <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" />
- </field>
-
- <field name = "passive" domain = "bit" label = "do not create queue">
- <doc>
- If set, the server will not create the queue. This field allows the client
- to assert the presence of a queue without modifying the server state.
- </doc>
- <rule name = "passive" on-failure = "not-found">
- <doc>
- The client MAY ask the server to assert that a queue exists without
- creating the queue if not. If the queue does not exist, the server
- treats this as a failure.
- </doc>
- <doc type = "scenario">
- Client declares an existing queue with the passive option and expects
- the server to respond with a declare-ok. Client then attempts to declare
- a non-existent queue with the passive option, and the server must close
- the channel with the correct reply-code.
- </doc>
- </rule>
- </field>
-
- <field name = "durable" domain = "bit" label = "request a durable queue">
- <doc>
- If set when creating a new queue, the queue will be marked as durable. Durable
- queues remain active when a server restarts. Non-durable queues (transient
- queues) are purged if/when a server restarts. Note that durable queues do not
- necessarily hold persistent messages, although it does not make sense to send
- persistent messages to a transient queue.
- </doc>
- <!-- Rule test name: was "amq_queue_03" -->
- <rule name = "persistence">
- <doc>The server MUST recreate the durable queue after a restart.</doc>
-
- <!-- TODO: use 'client does something' rather than 'a client does something'. -->
- <doc type = "scenario">
- A client creates a durable queue. The server is then restarted. The client
- then attempts to send a message to the queue. The message should be successfully
- delivered.
- </doc>
- </rule>
- <!-- Rule test name: was "amq_queue_36" -->
- <rule name = "types">
- <doc>The server MUST support both durable and transient queues.</doc>
- <doc type = "scenario">
- A client creates two named queues, one durable and one transient.
- </doc>
- </rule>
- <!-- Rule test name: was "amq_queue_37" -->
- <rule name = "pre-existence">
- <doc>The server MUST ignore the durable field if the queue already exists.</doc>
- <doc type = "scenario">
- A client creates two named queues, one durable and one transient. The client
- then attempts to declare the two queues using the same names again, but reversing
- the value of the durable flag in each case. Verify that the queues still exist
- with the original durable flag values.
- <!-- TODO: but how? -->
- </doc>
- </rule>
- </field>
-
- <field name = "exclusive" domain = "bit" label = "request an exclusive queue">
- <doc>
- Exclusive queues may only be consumed from by the current connection. Setting
- the 'exclusive' flag always implies 'auto-delete'.
- </doc>
-
- <!-- Rule test name: was "amq_queue_38" -->
- <rule name = "types">
- <doc>
- The server MUST support both exclusive (private) and non-exclusive (shared)
- queues.
- </doc>
- <doc type = "scenario">
- A client creates two named queues, one exclusive and one non-exclusive.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_04" -->
- <rule name = "02" on-failure = "channel-error">
- <doc>
- The client MAY NOT attempt to declare any existing and exclusive queue
- on multiple connections.
- </doc>
- <doc type = "scenario">
- A client declares an exclusive named queue. A second client on a different
- connection attempts to declare a queue of the same name.
- </doc>
- </rule>
- </field>
-
- <field name = "auto-delete" domain = "bit" label = "auto-delete queue when unused">
- <doc>
- If set, the queue is deleted when all consumers have finished using it. Last
- consumer can be cancelled either explicitly or because its channel is closed. If
- there was no consumer ever on the queue, it won't be deleted.
- </doc>
-
- <!-- Rule test name: was "amq_queue_31" -->
- <rule name = "pre-existence">
- <doc>
- The server MUST ignore the auto-delete field if the queue already exists.
- </doc>
- <doc type = "scenario">
- A client creates two named queues, one as auto-delete and one explicit-delete.
- The client then attempts to declare the two queues using the same names again,
- but reversing the value of the auto-delete field in each case. Verify that the
- queues still exist with the original auto-delete flag values.
- <!-- TODO: but how? -->
- </doc>
- </rule>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
-
- <field name = "arguments" domain = "table" label = "arguments for declaration">
- <doc>
- A set of arguments for the declaration. The syntax and semantics of these
- arguments depends on the server implementation. This field is ignored if passive
- is 1.
- </doc>
- </field>
- </method>
-
- <method name = "declare-ok" synchronous = "1" index = "11" label = "confirms a queue definition">
- <doc>
- This method confirms a Declare method and confirms the name of the queue, essential
- for automatically-named queues.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Reports the name of the queue. If the server generated a queue name, this field
- contains that name.
- </doc>
- <assert check = "notnull" />
- </field>
-
- <field name = "message-count" domain = "long" label = "number of messages in queue">
- <doc>
- Reports the number of messages in the queue, which will be zero for
- newly-created queues.
- </doc>
- </field>
-
- <field name = "consumer-count" domain = "long" label = "number of consumers">
- <doc>
- Reports the number of active consumers for the queue. Note that consumers can
- suspend activity (Channel.Flow) in which case they do not appear in this count.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "bind" synchronous = "1" index = "20" label = "bind queue to an exchange">
- <doc>
- This method binds a queue to an exchange. Until a queue is bound it will not receive
- any messages. In a classic messaging model, store-and-forward queues are bound to a
- dest exchange and subscription queues are bound to a dest_wild exchange.
- </doc>
-
- <!-- Rule test name: was "amq_queue_25" -->
- <rule name = "duplicates">
- <doc>
- A server MUST allow ignore duplicate bindings - that is, two or more bind
- methods for a specific queue, with identical arguments - without treating these
- as an error.
- </doc>
- <doc type = "scenario">
- A client binds a named queue to an exchange. The client then repeats the bind
- (with identical arguments).
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_39" -->
- <rule name = "failure" on-failure = "??????">
- <!--
- TODO: Find correct code. The on-failure code returned should depend on why the bind
- failed. Assuming that failures owing to bad parameters are covered in the rules relating
- to those parameters, the only remaining reason for a failure would be the lack of
- server resorces or some internal error - such as too many queues open. Would these
- cases qualify as "resource error" 506 or "internal error" 541?
- -->
- <doc>If a bind fails, the server MUST raise a connection exception.</doc>
- <doc type = "scenario">
- TODO
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_12" -->
- <rule name = "transient-exchange" on-failure = "not-allowed">
- <doc>
- The server MUST NOT allow a durable queue to bind to a transient exchange.
- </doc>
- <doc type = "scenario">
- A client creates a transient exchange. The client then declares a named durable
- queue and then attempts to bind the transient exchange to the durable queue.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_13" -->
- <rule name = "durable-exchange">
- <doc>
- Bindings for durable queues are automatically durable and the server SHOULD
- restore such bindings after a server restart.
- </doc>
- <doc type = "scenario">
- A server creates a named durable queue and binds it to a durable exchange. The
- server is restarted. The client then attempts to use the queue/exchange combination.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_17" -->
- <rule name = "internal-exchange">
- <doc>
- If the client attempts to bind to an exchange that was declared as internal, the server
- MUST raise a connection exception with reply code 530 (not allowed).
- </doc>
- <doc type = "scenario">
- A client attempts to bind a named queue to an internal exchange.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_40" -->
- <rule name = "binding-count">
- <doc>
- The server SHOULD support at least 4 bindings per queue, and ideally, impose no
- limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- A client creates a named queue and attempts to bind it to 4 different non-internal
- exchanges.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "bind-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- The client provides a valid access ticket giving "active" access rights to the
- queue's access realm.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to bind. If the queue name is empty, refers to
- the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "empty-queue" on-failure = "not-allowed">
- <doc>
- A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e.
- empty queue name) to an exchange.
- </doc>
- <doc type = "scenario">
- A client attempts to bind with an unnamed (empty) queue name to an exchange.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_26" -->
- <rule name = "queue-existence" on-failure = "not-found">
- <doc>
- A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously
- declared) to an exchange.
- </doc>
- <doc type = "scenario">
- A client attempts to bind an undeclared queue name to an exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name" label = "name of the exchange to bind to">
- <!-- Rule test name: was "amq_queue_14" -->
- <rule name = "exchange-existence" on-failure = "not-found">
- <doc>
- A client MUST NOT be allowed to bind a queue to a non-existent exchange.
- </doc>
- <doc type = "scenario">
- A client attempts to bind an named queue to a undeclared exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "message routing key">
- <doc>
- Specifies the routing key for the binding. The routing key is used for routing
- messages depending on the exchange configuration. Not all exchanges use a
- routing key - refer to the specific exchange documentation. If the queue name
- is empty, the server uses the last queue declared on the channel. If the
- routing key is also empty, the server uses this queue name for the routing
- key as well. If the queue name is provided but the routing key is empty, the
- server does the binding with that empty routing key. The meaning of empty
- routing keys depends on the exchange implementation.
- </doc>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
-
- <field name = "arguments" domain = "table" label = "arguments for binding">
- <doc>
- A set of arguments for the binding. The syntax and semantics of these arguments
- depends on the exchange class.
- </doc>
- </field>
- </method>
-
- <method name = "bind-ok" synchronous = "1" index = "21" label = "confirm bind successful">
- <doc>This method confirms that the bind was successful.</doc>
-
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "purge" synchronous = "1" index = "30" label = "purge a queue">
- <doc>
- This method removes all messages from a queue. It does not cancel consumers. Purged
- messages are deleted without any formal "undo" mechanism.
- </doc>
-
- <!-- Rule test name: was "amq_queue_15" -->
- <rule name = "01">
- <doc>A call to purge MUST result in an empty queue.</doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_41" -->
- <rule name = "02">
- <doc>
- On transacted channels the server MUST not purge messages that have already been
- sent to a client but not yet acknowledged.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <!-- Rule test name: was "amq_queue_42" -->
- <rule name = "03">
- <doc>
- The server MAY implement a purge queue or log that allows system administrators
- to recover accidentally-purged messages. The server SHOULD NOT keep purged
- messages in the same storage spaces as the live messages since the volumes of
- purged messages may get very large.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "purge-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>The access ticket must be for the access realm that holds the queue.</doc>
-
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the queue's access realm. Note that purging a queue is equivalent to reading
- all messages and discarding them.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to purge. If the queue name is empty, refers to
- the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
-
- <!-- TODO Rule split? -->
-
- <!-- Rule test name: was "amq_queue_16" -->
- <rule name = "02">
- <doc>
- The queue MUST exist. Attempting to purge a non-existing queue MUST cause a
- channel exception.
- </doc>
- </rule>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "purge-ok" synchronous = "1" index = "31" label = "confirms a queue purge">
- <doc>This method confirms the purge of a queue.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "message-count" domain = "long" label = "number of messages purged">
- <doc>Reports the number of messages purged.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "delete" synchronous = "1" index = "40" label = "delete a queue">
- <doc>
- This method deletes a queue. When a queue is deleted any pending messages are sent
- to a dead-letter queue if this is defined in the server configuration, and all
- consumers on the queue are cancelled.
- </doc>
-
- <!-- TODO: Rule split? -->
-
- <!-- Rule test name: was "amq_queue_43" -->
- <rule name = "01">
- <doc>
- The server SHOULD use a dead-letter queue to hold messages that were pending on
- a deleted queue, and MAY provide facilities for a system administrator to move
- these messages back to an active queue.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "delete-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <doc>
- The client provides a valid access ticket giving "active" access rights to the
- queue's access realm.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to delete. If the queue name is empty, refers to
- the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_queue_21" -->
- <rule name = "02">
- <doc>
- The queue must exist. If the client attempts to delete a non-existing queue
- the server MUST raise a channel exception with reply code 404 (not found).
- </doc>
- </rule>
- </field>
-
- <field name = "if-unused" domain = "bit" label = "delete only if unused">
- <doc>
- If set, the server will only delete the queue if it has no consumers. If the
- queue has consumers the server does does not delete it but raises a channel
- exception instead.
- </doc>
-
- <!-- Rule test name: was "amq_queue_29" and "amq_queue_30" -->
- <rule name = "01">
- <doc>The server MUST respect the if-unused flag when deleting a queue.</doc>
- </rule>
- </field>
-
- <field name = "if-empty" domain = "bit" label = "delete only if empty">
- <doc>
- If set, the server will only delete the queue if it has no messages.
- </doc>
- <rule name = "01">
- <doc>
- If the queue is not empty the server MUST raise a channel exception with
- reply code 406 (precondition failed).
- </doc>
- </rule>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "delete-ok" synchronous = "1" index = "41" label = "confirm deletion of a queue">
- <doc>This method confirms the deletion of a queue.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "message-count" domain = "long" label = "number of messages purged">
- <doc>Reports the number of messages purged.</doc>
- </field>
- </method>
- </class>
-
- <!-- == BASIC ============================================================ -->
-
- <class name = "basic" handler = "channel" index = "60" label = "work with basic content">
- <doc>
- The Basic class provides methods that support an industry-standard messaging model.
- </doc>
-
- <doc type = "grammar">
- basic = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:PUBLISH content
- / S:RETURN content
- / S:DELIVER content
- / C:GET ( S:GET-OK content / S:GET-EMPTY )
- / C:ACK
- / C:REJECT
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MAY" />
-
- <!-- Rule test name: was "amq_basic_08" -->
- <rule name = "01">
- <doc>
- The server SHOULD respect the persistent property of basic messages and
- SHOULD make a best-effort to hold persistent basic messages on a reliable
- storage mechanism.
- </doc>
- <doc type = "scenario">
- Send a persistent message to queue, stop server, restart server and then
- verify whether message is still present. Assumes that queues are durable.
- Persistence without durable queues makes no sense.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_09" -->
- <rule name = "02">
- <doc>
- The server MUST NOT discard a persistent basic message in case of a queue
- overflow.
- </doc>
- <doc type = "scenario">
- Create a queue overflow situation with persistent messages and verify that
- messages do not get lost (presumably the server will write them to disk).
- </doc>
- </rule>
-
- <rule name = "03">
- <doc>
- The server MAY use the Channel.Flow method to slow or stop a basic message
- publisher when necessary.
- </doc>
- <doc type = "scenario">
- Create a queue overflow situation with non-persistent messages and verify
- whether the server responds with Channel.Flow or not. Repeat with persistent
- messages.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_10" -->
- <rule name = "04">
- <doc>
- The server MAY overflow non-persistent basic messages to persistent
- storage.
- </doc>
- <!-- Test scenario: untestable -->
- </rule>
-
- <rule name = "05">
- <doc>
- The server MAY discard or dead-letter non-persistent basic messages on a
- priority basis if the queue size exceeds some configured limit.
- </doc>
- <!-- Test scenario: untestable -->
- </rule>
-
- <!-- Rule test name: was "amq_basic_11" -->
- <rule name = "06">
- <doc>
- The server MUST implement at least 2 priority levels for basic messages,
- where priorities 0-4 and 5-9 are treated as two distinct levels.
- </doc>
- <doc type = "scenario">
- Send a number of priority 0 messages to a queue. Send one priority 9
- message. Consume messages from the queue and verify that the first message
- received was priority 9.
- </doc>
- </rule>
-
- <rule name = "07">
- <doc>
- The server MAY implement up to 10 priority levels.
- </doc>
- <doc type = "scenario">
- Send a number of messages with mixed priorities to a queue, so that all
- priority values from 0 to 9 are exercised. A good scenario would be ten
- messages in low-to-high priority. Consume from queue and verify how many
- priority levels emerge.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_12" -->
- <rule name = "08">
- <doc>
- The server MUST deliver messages of the same priority in order irrespective of
- their individual persistence.
- </doc>
- <doc type = "scenario">
- Send a set of messages with the same priority but different persistence
- settings to a queue. Consume and verify that messages arrive in same order
- as originally published.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_13" -->
- <rule name = "09">
- <doc>
- The server MUST support automatic acknowledgements on Basic content, i.e.
- consumers with the no-ack field set to FALSE.
- </doc>
- <doc type = "scenario">
- Create a queue and a consumer using automatic acknowledgements. Publish
- a set of messages to the queue. Consume the messages and verify that all
- messages are received.
- </doc>
- </rule>
-
- <rule name = "10">
- <doc>
- The server MUST support explicit acknowledgements on Basic content, i.e.
- consumers with the no-ack field set to TRUE.
- </doc>
- <doc type = "scenario">
- Create a queue and a consumer using explicit acknowledgements. Publish a
- set of messages to the queue. Consume the messages but acknowledge only
- half of them. Disconnect and reconnect, and consume from the queue.
- Verify that the remaining messages are received.
- </doc>
- </rule>
-
- <!-- These are the properties for a Basic content -->
-
- <field name = "content-type" domain = "shortstr" label = "MIME content type" />
- <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" />
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "delivery-mode" domain = "octet" label = "non-persistent (1) or persistent (2)" />
- <field name = "priority" domain = "octet" label = "message priority, 0 to 9" />
- <field name = "correlation-id" domain = "shortstr" label = "application correlation identifier" />
- <field name = "reply-to" domain = "shortstr" label = "destination to reply to" />
- <field name = "expiration" domain = "shortstr" label = "message expiration specification" />
- <field name = "message-id" domain = "shortstr" label = "application message identifier" />
- <field name = "timestamp" domain = "timestamp" label = "message timestamp" />
- <field name = "type" domain = "shortstr" label = "message type name" />
- <field name = "user-id" domain = "shortstr" label = "creating user id" />
- <field name = "app-id" domain = "shortstr" label = "creating application id" />
- <!-- This field is deprecated pending review -->
- <field name = "cluster-id" domain = "shortstr" label = "intra-cluster routing identifier" />
-
- <field name = "property-one" domain = "shortstr" label = "Extra property for testing only" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
- <doc>
- This method requests a specific quality of service. The QoS can be specified for the
- current channel or for all channels on the connection. The particular properties and
- semantics of a qos method always depend on the content class semantics. Though the
- qos method could in principle apply to both peers, it is currently meaningful only
- for the server.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "qos-ok" />
-
- <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
- <doc>
- The client can request that messages be sent in advance so that when the client
- finishes processing a message, the following message is already held locally,
- rather than needing to be sent down the channel. Prefetching gives a performance
- improvement. This field specifies the prefetch window size in octets. The server
- will send a message in advance if it is equal to or smaller in size than the
- available prefetch size (and also falls into other prefetch limits). May be set
- to zero, meaning "no specific limit", although other prefetch limits may still
- apply. The prefetch-size is ignored if the no-ack option is set.
- </doc>
- <!-- Rule test name: was "amq_basic_17" -->
- <rule name = "01">
- <doc>
- The server MUST ignore this setting when the client is not processing any
- messages - i.e. the prefetch size does not limit the transfer of single
- messages to a client, only the sending in advance of more messages while
- the client still has one or more unacknowledged messages.
- </doc>
- <doc type = "scenario">
- Define a QoS prefetch-size limit and send a single message that exceeds
- that limit. Verify that the message arrives correctly.
- </doc>
- </rule>
- </field>
-
- <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
- <doc>
- Specifies a prefetch window in terms of whole messages. This field may be used
- in combination with the prefetch-size field; a message will only be sent in
- advance if both prefetch windows (and those at the channel and connection level)
- allow it. The prefetch-count is ignored if the no-ack option is set.
- </doc>
- <!-- Rule test name: was "amq_basic_18" -->
- <rule name = "01">
- <doc>
- The server may send less data in advance than allowed by the client's
- specified prefetch windows but it MUST NOT send more.
- </doc>
- <doc type = "scenario">
- Define a QoS prefetch-size limit and a prefetch-count limit greater than
- one. Send multiple messages that exceed the prefetch size. Verify that
- no more than one message arrives at once.
- </doc>
- </rule>
- </field>
-
- <field name = "global" domain = "bit" label = "apply to entire connection">
- <doc>
- By default the QoS settings apply to the current channel only. If this field is
- set, they are applied to the entire connection.
- </doc>
- </field>
- </method>
-
- <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
- <doc>
- This method tells the client that the requested QoS levels could be handled by the
- server. The requested QoS applies to all active consumers until a new QoS is
- defined.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "consume" synchronous = "1" index = "30" label = "start a queue consumer">
- <doc>
- This method asks the server to start a "consumer", which is a transient request for
- messages from a specific queue. Consumers last as long as the channel they were
- created on, or until the client cancels them.
- </doc>
-
- <!-- Rule test name: was "amq_basic_01" -->
- <rule name = "01">
- <doc>
- The server SHOULD support at least 16 consumers per queue, and ideally, impose
- no limit except as defined by available resources.
- </doc>
- <doc type = "scenario">
- Create a queue and create consumers on that queue until the server closes the
- connection. Verify that the number of consumers created was at least sixteen
- and report the total number.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01" on-failure = "access-refused">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- <doc type = "scenario">
- Attempt to create a consumer with an invalid (non-zero) access ticket.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
- <rule name = "01" on-failure = "not-allowed">
- <doc>
- If the queue name is empty the client MUST have previously declared a
- queue using this channel.
- </doc>
- <doc type = "scenario">
- Attempt to create a consumer with an empty queue name and no previously
- declared queue on the channel.
- </doc>
- </rule>
- </field>
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is local to a
- connection, so two clients can use the same consumer tags. If this field is
- empty the server will generate a unique tag.
- </doc>
- <rule name = "01" on-failure = "not-allowed">
- <doc>
- The client MUST NOT specify a tag that refers to an existing consumer.
- </doc>
- <doc type = "scenario">
- Attempt to create two consumers with the same non-empty tag.
- </doc>
- </rule>
- <rule name = "02" on-failure = "not-allowed">
- <doc>
- The consumer tag is valid only within the channel from which the
- consumer was created. I.e. a client MUST NOT create a consumer in one
- channel and then use it in another.
- </doc>
- <doc type = "scenario">
- Attempt to create a consumer in one channel, then use in another channel,
- in which consumers have also been created (to test that the server uses
- unique consumer tags).
- </doc>
- </rule>
- </field>
-
- <field name = "no-local" domain = "no-local" />
-
- <field name = "no-ack" domain = "no-ack" />
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive consumer access, meaning only this consumer can access the
- queue.
- </doc>
- <!-- Rule test name: was "amq_basic_02" -->
- <rule name = "01" on-failure = "access-refused">
- <doc>
- The client MAY NOT gain exclusive access to a queue that already has
- active consumers.
- </doc>
- <doc type = "scenario">
- Open two connections to a server, and in one connection create a shared
- (non-exclusive) queue and then consume from the queue. In the second
- connection attempt to consume from the same queue using the exclusive
- option.
- </doc>
- </rule>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise
- a channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "consume-ok" synchronous = "1" index = "31" label = "confirm a new consumer">
- <doc>
- The server provides the client with a consumer tag, which is used by the client
- for methods called on the consumer at a later stage.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Holds the consumer tag specified by the client or provided by the server.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "cancel" synchronous = "1" index = "20" label = "end a queue consumer">
- <doc>
- This method cancels a consumer. This does not affect already delivered
- messages, but it does mean the server will not send any more messages for
- that consumer. The client may receive an abitrary number of messages in
- between sending the cancel method and receiving the cancel-ok reply.
- </doc>
-
- <rule name = "01">
- <doc>
- If the queue does not exist the server MUST ignore the cancel method, so
- long as the consumer tag is valid for that channel.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "cancel-ok" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "cancel-ok" synchronous = "1" index = "21" label = "confirm a cancelled consumer">
- <doc>
- This method confirms that the cancellation was completed.
- </doc>
- <chassis name = "client" implement = "MUST" />
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "publish" content = "1" index = "40" label = "publish a message">
- <doc>
- This method publishes a message to a specific exchange. The message will be routed
- to queues as defined by the exchange configuration and distributed to any active
- consumers when the transaction, if any, is committed.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "write" access rights
- to the access realm for the exchange.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange name can be
- empty, meaning the default exchange. If the exchange name is specified, and that
- exchange does not exist, the server will raise a channel exception.
- </doc>
-
- <!-- Rule test name: was "amq_basic_06" -->
- <rule name = "01">
- <doc>
- The server MUST accept a blank exchange name to mean the default exchange.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_14" -->
- <rule name = "02">
- <doc>
- If the exchange was declared as an internal exchange, the server MUST raise
- a channel exception with a reply code 403 (access refused).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_15" -->
- <rule name = "03">
- <doc>
- The exchange MAY refuse basic content in which case it MUST raise a channel
- exception with reply code 540 (not implemented).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "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 = "mandatory" domain = "bit" label = "indicate mandatory routing">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue. If this flag is set, the server will return an unroutable message with a
- Return method. If this flag is zero, the server silently drops the message.
- </doc>
- <!-- Rule test name: was "amq_basic_07" -->
- <rule name = "01">
- <doc>
- The server SHOULD implement the mandatory flag.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "immediate" domain = "bit" label = "request immediate delivery">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue consumer immediately. If this flag is set, the server will return an
- undeliverable message with a Return method. If this flag is zero, the server
- will queue the message, but with no guarantee that it will ever be consumed.
- </doc>
- <!-- Rule test name: was "amq_basic_16" -->
- <rule name = "01">
- <doc>
- The server SHOULD implement the immediate flag.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "return" content = "1" index = "50" label = "return a failed message">
- <doc>
- This method returns an undeliverable message that was published with the "immediate"
- flag set, or an unroutable message published with the "mandatory" flag set. The
- reply code and text provide information about the reason that the message was
- undeliverable.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply-code" domain = "reply-code" />
-
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>
- Specifies the routing key name specified when the message was published.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "deliver" content = "1" index = "60"
- label = "notify the client of a consumer message">
- <doc>
- This method delivers a message to the client, via a consumer. In the asynchronous
- message delivery model, the client starts a consumer using the Consume method, then
- the server responds with Deliver methods as and when messages arrive for that
- consumer.
- </doc>
-
- <!-- Rule test name: was "amq_basic_19" -->
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server SHOULD track the number of times a message has been delivered to
- clients and when a message is redelivered a certain number of times - e.g. 5
- times - without being acknowledged, the server SHOULD consider the message to be
- unprocessable (possibly causing client applications to abort), and move the
- message to a dead letter queue.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "get" synchronous = "1" index = "70" label = "direct access to a queue">
- <doc>
- This method provides a direct access to the messages in a queue using a synchronous
- dialogue that is designed for specific types of application where synchronous
- functionality is more important than performance.
- </doc>
-
- <response name = "get-ok" />
- <response name = "get-empty" />
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
-
- <field name = "no-ack" domain = "no-ack" />
- </method>
-
- <method name = "get-ok" synchronous = "1" content = "1" index = "71"
- label = "provide client with a message">
- <doc>
- This method delivers a message to the client following a get method. A message
- delivered by 'get-ok' must be acknowledged unless the no-ack option was set in the
- get method.
- </doc>
-
- <chassis name = "client" implement = "MAY" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- If empty, the message was published to the default exchange.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
-
- <field name = "message-count" domain = "long" label = "number of messages pending">
- <doc>
- This field reports the number of messages pending on the queue, excluding the
- message being delivered. Note that this figure is indicative, not reliable, and
- can change arbitrarily as messages are added to the queue and removed by other
- clients.
- </doc>
- </field>
- </method>
-
- <method name = "get-empty" synchronous = "1" index = "72"
- label = "indicate no messages available">
- <doc>
- This method tells the client that the queue has no messages available for the
- client.
- </doc>
-
- <chassis name = "client" implement = "MAY" />
-
- <!-- This field is deprecated pending review -->
- <field name = "cluster-id" domain = "shortstr" label = "Cluster id">
- <doc>
- For use by cluster applications, should not be used by client applications.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "ack" index = "80" label = "acknowledge one or more messages">
- <doc>
- This method acknowledges one or more messages delivered via the Deliver or Get-Ok
- methods. The client can ask to confirm a single message or a set of messages up to
- and including a specific message.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "multiple" domain = "bit" label = "acknowledge multiple messages">
- <doc>
- If set to 1, the delivery tag is treated as "up to and including", so that the
- client can acknowledge multiple messages with a single method. If set to zero,
- the delivery tag refers to a single message. If the multiple field is 1, and the
- delivery tag is zero, tells the server to acknowledge all outstanding mesages.
- </doc>
-
- <!-- Rule test name: was "amq_basic_20" -->
- <rule name = "01">
- <doc>
- The server MUST validate that a non-zero delivery-tag refers to an delivered
- message, and raise a channel exception if this is not the case.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "reject" index = "90" label = "reject an incoming message">
- <doc>
- This method allows a client to reject a message. It can be used to interrupt and
- cancel large incoming messages, or return untreatable messages to their original
- queue.
- </doc>
-
- <!-- Rule test name: was "amq_basic_21" -->
- <rule name = "01">
- <doc>
- The server SHOULD be capable of accepting and process the Reject method while
- sending message content with a Deliver or Get-Ok method. I.e. the server should
- read and process incoming methods while sending output frames. To cancel a
- partially-send content, the server sends a content body frame of size 1 (i.e.
- with no data except the frame-end octet).
- </doc>
- </rule>
-
- <!-- Rule test name: was "amq_basic_22" -->
- <rule name = "02">
- <doc>
- The server SHOULD interpret this method as meaning that the client is unable to
- process the message at this time.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <rule name = "03">
- <!-- TODO: Rule split? -->
- <doc>
- A client MUST NOT use this method as a means of selecting messages to process. A
- rejected message MAY be discarded or dead-lettered, not necessarily passed to
- another client.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "requeue" domain = "bit" label = "requeue the message">
- <doc>
- If this field is zero, the message will be discarded. If this bit is 1, the
- server will attempt to requeue the message.
- </doc>
-
- <!-- Rule test name: was "amq_basic_23" -->
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MUST NOT deliver the message to the same client within the
- context of the current channel. The recommended strategy is to attempt to
- deliver the message to an alternative consumer, and if that is not possible,
- to move the message to a dead-letter queue. The server MAY use more
- sophisticated tracking to hold the message on the queue and redeliver it to
- the same client at a later stage.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "recover" index = "100" label = "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>
-
- <rule name = "01">
- <doc>
- The server MUST set the redelivered flag on all messages that are resent.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- The server MUST raise a channel exception if this is called on a transacted
- channel.
- </doc>
- <doc type = "scenario">
- TODO.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "requeue" domain = "bit" label = "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>
- </method>
- </class>
-
- <!-- == FILE ============================================================= -->
-
- <class name = "file" handler = "channel" index = "70" label = "work with file content">
- <doc>
- The file class provides methods that support reliable file transfer. File
- messages have a specific set of properties that are required for interoperability
- with file transfer applications. File messages and acknowledgements are subject to
- channel transactions. Note that the file class does not provide message browsing
- methods; these are not compatible with the staging model. Applications that need
- browsable file transfer should use Basic content and the Basic class.
- </doc>
-
- <doc type = "grammar">
- file = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:OPEN S:OPEN-OK C:STAGE content
- / S:OPEN C:OPEN-OK S:STAGE content
- / C:PUBLISH
- / S:DELIVER
- / S:RETURN
- / C:ACK
- / C:REJECT
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <rule name = "01">
- <doc>
- The server MUST make a best-effort to hold file messages on a reliable storage
- mechanism.
- </doc>
- </rule>
-
- <!-- TODO Rule implement attr inverse? -->
-
- <!-- TODO: Rule split? -->
-
- <rule name = "02">
- <doc>
- The server MUST NOT discard a file message in case of a queue overflow. The server
- MUST use the Channel.Flow method to slow or stop a file message publisher when
- necessary.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "03">
- <doc>
- The server MUST implement at least 2 priority levels for file messages, where
- priorities 0-4 and 5-9 are treated as two distinct levels. The server MAY implement
- up to 10 priority levels.
- </doc>
- </rule>
-
- <rule name = "04">
- <doc>
- The server MUST support both automatic and explicit acknowledgements on file
- content.
- </doc>
- </rule>
-
- <!-- These are the properties for a File content -->
-
- <field name = "content-type" domain = "shortstr" label = "MIME content type" />
- <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" />
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "priority" domain = "octet" label = "message priority, 0 to 9" />
- <field name = "reply-to" domain = "shortstr" label = "destination to reply to" />
- <field name = "message-id" domain = "shortstr" label = "application message identifier" />
- <field name = "filename" domain = "shortstr" label = "message filename" />
- <field name = "timestamp" domain = "timestamp" label = "message timestamp" />
- <!-- This field is deprecated pending review -->
- <field name = "cluster-id" domain = "shortstr" label = "intra-cluster routing identifier" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
- <doc>
- This method requests a specific quality of service. The QoS can be specified for the
- current channel or for all channels on the connection. The particular properties and
- semantics of a qos method always depend on the content class semantics. Though the
- qos method could in principle apply to both peers, it is currently meaningful only
- for the server.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "qos-ok" />
-
- <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
- <doc>
- The client can request that messages be sent in advance so that when the client
- finishes processing a message, the following message is already held locally,
- rather than needing to be sent down the channel. Prefetching gives a performance
- improvement. This field specifies the prefetch window size in octets. May be set
- to zero, meaning "no specific limit". Note that other prefetch limits may still
- apply. The prefetch-size is ignored if the no-ack option is set.
- </doc>
- </field>
-
- <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
- <doc>
- Specifies a prefetch window in terms of whole messages. This is compatible with
- some file API implementations. This field may be used in combination with the
- prefetch-size field; a message will only be sent in advance if both prefetch
- windows (and those at the channel and connection level) allow it. The
- prefetch-count is ignored if the no-ack option is set.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MAY send less data in advance than allowed by the client's
- specified prefetch windows but it MUST NOT send more.
- </doc>
- </rule>
- </field>
-
- <field name = "global" domain = "bit" label = "apply to entire connection">
- <doc>
- By default the QoS settings apply to the current channel only. If this field is
- set, they are applied to the entire connection.
- </doc>
- </field>
- </method>
-
- <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
- <doc>
- This method tells the client that the requested QoS levels could be handled by the
- server. The requested QoS applies to all active consumers until a new QoS is
- defined.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
- <doc>
- This method asks the server to start a "consumer", which is a transient request for
- messages from a specific queue. Consumers last as long as the channel they were
- created on, or until the client cancels them.
- </doc>
-
- <rule name = "01">
- <doc>
- The server SHOULD support at least 16 consumers per queue, unless the queue was
- declared as private, and ideally, impose no limit except as defined by available
- resources.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is local to a
- connection, so two clients can use the same consumer tags. If this field is
- empty the server will generate a unique tag.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The tag MUST NOT refer to an existing consumer. If the client attempts to
- create two consumers with the same non-empty tag the server MUST raise a
- connection exception with reply code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "no-local" domain = "no-local" />
-
- <field name = "no-ack" domain = "no-ack" />
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive consumer access, meaning only this consumer can access the
- queue.
- </doc>
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>
- If the server cannot grant exclusive access to the queue when asked, -
- because there are other consumers active - it MUST raise a channel exception
- with return code 405 (resource locked).
- </doc>
- </rule>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
- <doc>
- This method provides the client with a consumer tag which it MUST use in methods
- that work with the consumer.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>Holds the consumer tag specified by the client or provided by the server.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
- <doc>
- This method cancels a consumer. This does not affect already delivered messages, but
- it does mean the server will not send any more messages for that consumer.
- </doc>
-
- <response name = "cancel-ok" />
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
- <doc>This method confirms that the cancellation was completed.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "open" synchronous = "1" index = "40" label = "request to start staging">
- <doc>
- This method requests permission to start staging a message. Staging means sending
- the message into a temporary area at the recipient end and then delivering the
- message by referring to this temporary area. Staging is how the protocol handles
- partial file transfers - if a message is partially staged and the connection breaks,
- the next time the sender starts to stage it, it can restart from where it left off.
- </doc>
-
- <response name = "open-ok" />
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <field name = "identifier" domain = "shortstr" label = "staging identifier">
- <doc>
- This is the staging identifier. This is an arbitrary string chosen by the
- sender. For staging to work correctly the sender must use the same staging
- identifier when staging the same message a second time after recovery from a
- failure. A good choice for the staging identifier would be the SHA1 hash of the
- message properties data (including the original filename, revised time, etc.).
- </doc>
- </field>
-
- <field name = "content-size" domain = "longlong" label = "message content size">
- <doc>
- The size of the content in octets. The recipient may use this information to
- allocate or check available space in advance, to avoid "disk full" errors during
- staging of very large messages.
- </doc>
-
- <rule name = "01">
- <doc>
- The sender MUST accurately fill the content-size field. Zero-length content
- is permitted.
- </doc>
- </rule>
- </field>
- </method>
-
- <method name = "open-ok" synchronous = "1" index = "41" label = "confirm staging ready">
- <doc>
- This method confirms that the recipient is ready to accept staged data. If the
- message was already partially-staged at a previous time the recipient will report
- the number of octets already staged.
- </doc>
-
- <response name = "stage" />
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
-
- <field name = "staged-size" domain = "longlong" label = "already staged amount">
- <doc>
- The amount of previously-staged content in octets. For a new message this will
- be zero.
- </doc>
-
- <rule name = "01">
- <doc>
- The sender MUST start sending data from this octet offset in the message,
- counting from zero.
- </doc>
- </rule>
-
- <rule name = "02">
- <!-- TODO: Rule split? -->
- <doc>
- The recipient MAY decide how long to hold partially-staged content and MAY
- implement staging by always discarding partially-staged content. However if
- it uses the file content type it MUST support the staging methods.
- </doc>
- </rule>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "stage" content = "1" index = "50" label = "stage message content">
- <doc>
- This method stages the message, sending the message content to the recipient from
- the octet offset specified in the Open-Ok method.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "publish" index = "60" label = "publish a message">
- <doc>
- This method publishes a staged file message to a specific exchange. The file message
- will be routed to queues as defined by the exchange configuration and distributed to
- any active consumers when the transaction, if any, is committed.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "write" access rights
- to the access realm for the exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange name can be
- empty, meaning the default exchange. If the exchange name is specified, and that
- exchange does not exist, the server will raise a channel exception.
- </doc>
-
- <rule name = "01">
- <doc>
- The server MUST accept a blank exchange name to mean the default exchange.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- If the exchange was declared as an internal exchange, the server MUST
- respond with a reply code 403 (access refused) and raise a channel
- exception.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "03">
- <doc>
- The exchange MAY refuse file content in which case it MUST respond with a
- reply code 540 (not implemented) and raise a channel exception.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "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 = "mandatory" domain = "bit" label = "indicate mandatory routing">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue. If this flag is set, the server will return an unroutable message with a
- Return method. If this flag is zero, the server silently drops the message.
- </doc>
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the mandatory flag.</doc>
- </rule>
- </field>
-
- <field name = "immediate" domain = "bit" label = "request immediate delivery">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue consumer immediately. If this flag is set, the server will return an
- undeliverable message with a Return method. If this flag is zero, the server
- will queue the message, but with no guarantee that it will ever be consumed.
- </doc>
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the immediate flag.</doc>
- </rule>
- </field>
-
- <field name = "identifier" domain = "shortstr" label = "staging identifier">
- <doc>
- This is the staging identifier of the message to publish. The message must have
- been staged. Note that a client can send the Publish method asynchronously
- without waiting for staging to finish.
- </doc>
- </field>
- </method>
-
- <method name = "return" content = "1" index = "70" label = "return a failed message">
- <doc>
- This method returns an undeliverable message that was published with the "immediate"
- flag set, or an unroutable message published with the "mandatory" flag set. The
- reply code and text provide information about the reason that the message was
- undeliverable.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply-code" domain = "reply-code" />
-
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "deliver" index = "80" label = "notify the client of a consumer message">
- <doc>
- This method delivers a staged file message to the client, via a consumer. In the
- asynchronous message delivery model, the client starts a consumer using the Consume
- method, then the server responds with Deliver methods as and when messages arrive
- for that consumer.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server SHOULD track the number of times a message has been delivered to
- clients and when a message is redelivered a certain number of times - e.g. 5
- times - without being acknowledged, the server SHOULD consider the message to be
- unprocessable (possibly causing client applications to abort), and move the
- message to a dead letter queue.
- </doc>
- </rule>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "redelivered" domain = "redelivered" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
-
- <field name = "identifier" domain = "shortstr" label = "staging identifier">
- <doc>
- This is the staging identifier of the message to deliver. The message must have
- been staged. Note that a server can send the Deliver method asynchronously
- without waiting for staging to finish.
- </doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "ack" index = "90" label = "acknowledge one or more messages">
- <doc>
- This method acknowledges one or more messages delivered via the Deliver method. The
- client can ask to confirm a single message or a set of messages up to and including
- a specific message.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "multiple" domain = "bit" label = "acknowledge multiple messages">
- <doc>
- If set to 1, the delivery tag is treated as "up to and including", so that the
- client can acknowledge multiple messages with a single method. If set to zero,
- the delivery tag refers to a single message. If the multiple field is 1, and the
- delivery tag is zero, tells the server to acknowledge all outstanding mesages.
- </doc>
-
- <rule name = "01">
- <doc>
- The server MUST validate that a non-zero delivery-tag refers to an delivered
- message, and raise a channel exception if this is not the case.
- </doc>
- </rule>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "reject" index = "100" label = "reject an incoming message">
- <doc>
- This method allows a client to reject a message. It can be used to return
- untreatable messages to their original queue. Note that file content is staged
- before delivery, so the client will not use this method to interrupt delivery of a
- large message.
- </doc>
-
- <rule name = "01">
- <doc>
- The server SHOULD interpret this method as meaning that the client is unable to
- process the message at this time.
- </doc>
- </rule>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "02">
- <doc>
- A client MUST NOT use this method as a means of selecting messages to process. A
- rejected message MAY be discarded or dead-lettered, not necessarily passed to
- another client.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "requeue" domain = "bit" label = "requeue the message">
- <doc>
- If this field is zero, the message will be discarded. If this bit is 1, the
- server will attempt to requeue the message.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MUST NOT deliver the message to the same client within the
- context of the current channel. The recommended strategy is to attempt to
- deliver the message to an alternative consumer, and if that is not possible,
- to move the message to a dead-letter queue. The server MAY use more
- sophisticated tracking to hold the message on the queue and redeliver it to
- the same client at a later stage.
- </doc>
- </rule>
- </field>
- </method>
- </class>
-
- <!-- == STREAM =========================================================== -->
-
- <class name = "stream" handler = "channel" index = "80" label = "work with streaming content">
- <doc>
- The stream class provides methods that support multimedia streaming. The stream class
- uses the following semantics: one message is one packet of data; delivery is
- unacknowleged and unreliable; the consumer can specify quality of service parameters
- that the server can try to adhere to; lower-priority messages may be discarded in favour
- of high priority messages.
- </doc>
-
- <doc type = "grammar">
- stream = C:QOS S:QOS-OK
- / C:CONSUME S:CONSUME-OK
- / C:CANCEL S:CANCEL-OK
- / C:PUBLISH content
- / S:RETURN
- / S:DELIVER content
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <rule name = "01">
- <doc>
- The server SHOULD discard stream messages on a priority basis if the queue size
- exceeds some configured limit.
- </doc>
- </rule>
-
- <rule name = "02">
- <!-- TODO: Rule split? -->
- <doc>
- The server MUST implement at least 2 priority levels for stream messages, where
- priorities 0-4 and 5-9 are treated as two distinct levels. The server MAY implement
- up to 10 priority levels.
- </doc>
- </rule>
-
- <rule name = "03">
- <doc>
- The server MUST implement automatic acknowledgements on stream content. That is, as
- soon as a message is delivered to a client via a Deliver method, the server must
- remove it from the queue.
- </doc>
- </rule>
-
- <!-- These are the properties for a Stream content -->
-
- <field name = "content-type" domain = "shortstr" label = "MIME content type" />
- <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" />
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "priority" domain = "octet" label = "message priority, 0 to 9" />
- <field name = "timestamp" domain = "timestamp" label = "message timestamp" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service">
- <doc>
- This method requests a specific quality of service. The QoS can be specified for the
- current channel or for all channels on the connection. The particular properties and
- semantics of a qos method always depend on the content class semantics. Though the
- qos method could in principle apply to both peers, it is currently meaningful only
- for the server.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "qos-ok" />
-
- <field name = "prefetch-size" domain = "long" label = "prefetch window in octets">
- <doc>
- The client can request that messages be sent in advance so that when the client
- finishes processing a message, the following message is already held locally,
- rather than needing to be sent down the channel. Prefetching gives a performance
- improvement. This field specifies the prefetch window size in octets. May be set
- to zero, meaning "no specific limit". Note that other prefetch limits may still
- apply.
- </doc>
- </field>
-
- <field name = "prefetch-count" domain = "short" label = "prefetch window in messages">
- <doc>
- Specifies a prefetch window in terms of whole messages. This field may be used
- in combination with the prefetch-size field; a message will only be sent in
- advance if both prefetch windows (and those at the channel and connection level)
- allow it.
- </doc>
- </field>
-
- <field name = "consume-rate" domain = "long" label = "transfer rate in octets/second">
- <doc>
- Specifies a desired transfer rate in octets per second. This is usually
- determined by the application that uses the streaming data. A value of zero
- means "no limit", i.e. as rapidly as possible.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The server MAY ignore the prefetch values and consume rates, depending on
- the type of stream and the ability of the server to queue and/or reply it.
- The server MAY drop low-priority messages in favour of high-priority
- messages.
- </doc>
- </rule>
- </field>
-
- <field name = "global" domain = "bit" label = "apply to entire connection">
- <doc>
- By default the QoS settings apply to the current channel only. If this field is
- set, they are applied to the entire connection.
- </doc>
- </field>
- </method>
-
- <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos">
- <doc>
- This method tells the client that the requested QoS levels could be handled by the
- server. The requested QoS applies to all active consumers until a new QoS is
- defined.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer">
- <doc>
- This method asks the server to start a "consumer", which is a transient request for
- messages from a specific queue. Consumers last as long as the channel they were
- created on, or until the client cancels them.
- </doc>
-
- <rule name = "01">
- <doc>
- The server SHOULD support at least 16 consumers per queue, unless the queue was
- declared as private, and ideally, impose no limit except as defined by available
- resources.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- Streaming applications SHOULD use different channels to select different
- streaming resolutions. AMQP makes no provision for filtering and/or transforming
- streams except on the basis of priority-based selective delivery of individual
- messages.
- </doc>
- </rule>
-
- <chassis name = "server" implement = "MUST" />
- <response name = "consume-ok" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "read" access rights to
- the realm for the queue.
- </doc>
- </rule>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue to consume from. If the queue name is null,
- refers to the current queue for the channel, which is the last declared queue.
- </doc>
-
- <rule name = "01">
- <doc>
- If the client did not previously declare a queue, and the queue name in this
- method is empty, the server MUST raise a connection exception with reply
- code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>
- Specifies the identifier for the consumer. The consumer tag is local to a
- connection, so two clients can use the same consumer tags. If this field is
- empty the server will generate a unique tag.
- </doc>
-
- <rule name = "01">
- <!-- TODO: Rule split? -->
- <doc>
- The tag MUST NOT refer to an existing consumer. If the client attempts to
- create two consumers with the same non-empty tag the server MUST raise a
- connection exception with reply code 530 (not allowed).
- </doc>
- </rule>
- </field>
-
- <field name = "no-local" domain = "no-local" />
-
- <field name = "exclusive" domain = "bit" label = "request exclusive access">
- <doc>
- Request exclusive consumer access, meaning only this consumer can access the
- queue.
- </doc>
-
-
- <!-- Rule test name: was "amq_file_00" -->
- <rule name = "01">
- <doc>
- If the server cannot grant exclusive access to the queue when asked, -
- because there are other consumers active - it MUST raise a channel exception
- with return code 405 (resource locked).
- </doc>
- </rule>
- </field>
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer">
- <doc>
- This method provides the client with a consumer tag which it may use in methods that
- work with the consumer.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag">
- <doc>Holds the consumer tag specified by the client or provided by the server.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer">
- <doc>
- This method cancels a consumer. Since message delivery is asynchronous the client
- may continue to receive messages for a short while after canceling a consumer. It
- may process or discard these as appropriate.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <response name = "cancel-ok" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "nowait" domain = "bit" label = "do not send a reply method">
- <doc>
- If set, the server will not respond to the method. The client should not wait
- for a reply method. If the server could not complete the method it will raise a
- channel or connection exception.
- </doc>
- </field>
- </method>
-
- <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer">
- <doc>This method confirms that the cancellation was completed.</doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "publish" content = "1" index = "40" label = "publish a message">
- <doc>
- This method publishes a message to a specific exchange. The message will be routed
- to queues as defined by the exchange configuration and distributed to any active
- consumers as appropriate.
- </doc>
-
- <chassis name = "server" implement = "MUST" />
-
- <field name = "ticket" domain = "access-ticket">
- <rule name = "01">
- <doc>
- The client MUST provide a valid access ticket giving "write" access rights
- to the access realm for the exchange.
- </doc>
- </rule>
- </field>
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange to publish to. The exchange name can be
- empty, meaning the default exchange. If the exchange name is specified, and that
- exchange does not exist, the server will raise a channel exception.
- </doc>
-
- <rule name = "01">
- <doc>
- The server MUST accept a blank exchange name to mean the default exchange.
- </doc>
- </rule>
-
- <rule name = "02">
- <doc>
- If the exchange was declared as an internal exchange, the server MUST
- respond with a reply code 403 (access refused) and raise a channel
- exception.
- </doc>
- </rule>
-
- <rule name = "03">
- <doc>
- The exchange MAY refuse stream content in which case it MUST respond with a
- reply code 540 (not implemented) and raise a channel exception.
- </doc>
- </rule>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "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 = "mandatory" domain = "bit" label = "indicate mandatory routing">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue. If this flag is set, the server will return an unroutable message with a
- Return method. If this flag is zero, the server silently drops the message.
- </doc>
-
- <!-- Rule test name: was "amq_stream_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the mandatory flag.</doc>
- </rule>
- </field>
-
- <field name = "immediate" domain = "bit" label = "request immediate delivery">
- <doc>
- This flag tells the server how to react if the message cannot be routed to a
- queue consumer immediately. If this flag is set, the server will return an
- undeliverable message with a Return method. If this flag is zero, the server
- will queue the message, but with no guarantee that it will ever be consumed.
- </doc>
-
- <!-- Rule test name: was "amq_stream_00" -->
- <rule name = "01">
- <doc>The server SHOULD implement the immediate flag.</doc>
- </rule>
- </field>
- </method>
-
- <method name = "return" content = "1" index = "50" label = "return a failed message">
- <doc>
- This method returns an undeliverable message that was published with the "immediate"
- flag set, or an unroutable message published with the "mandatory" flag set. The
- reply code and text provide information about the reason that the message was
- undeliverable.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "reply-code" domain = "reply-code" />
-
- <field name = "reply-text" domain = "reply-text" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "routing-key" domain = "shortstr" label = "Message routing key">
- <doc>Specifies the routing key name specified when the message was published.</doc>
- </field>
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "deliver" content = "1" index = "60"
- label = "notify the client of a consumer message">
- <doc>
- This method delivers a message to the client, via a consumer. In the asynchronous
- message delivery model, the client starts a consumer using the Consume method, then
- the server responds with Deliver methods as and when messages arrive for that
- consumer.
- </doc>
-
- <chassis name = "client" implement = "MUST" />
-
- <field name = "consumer-tag" domain = "consumer-tag" />
-
- <field name = "delivery-tag" domain = "delivery-tag" />
-
- <field name = "exchange" domain = "exchange-name">
- <doc>
- Specifies the name of the exchange that the message was originally published to.
- </doc>
- </field>
-
- <field name = "queue" domain = "queue-name">
- <doc>
- Specifies the name of the queue that the message came from. Note that a single
- channel can start many consumers on different queues.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
- </class>
-
- <!-- == TX =============================================================== -->
-
- <class name = "tx" handler = "channel" index = "90" label = "work with standard transactions">
- <doc>
- Standard transactions provide so-called "1.5 phase commit". We can ensure that work is
- never lost, but there is a chance of confirmations being lost, so that messages may be
- resent. Applications that use standard transactions must be able to detect and ignore
- duplicate messages.
- </doc>
-
- <!-- TODO: Rule split? -->
-
- <rule name = "01">
- <doc>
- An client using standard transactions SHOULD be able to track all messages received
- within a reasonable period, and thus detect and reject duplicates of the same
- message. It SHOULD NOT pass these to the application layer.
- </doc>
- </rule>
-
- <doc type = "grammar">
- tx = C:SELECT S:SELECT-OK
- / C:COMMIT S:COMMIT-OK
- / C:ROLLBACK S:ROLLBACK-OK
- </doc>
-
- <chassis name = "server" implement = "SHOULD" />
- <chassis name = "client" implement = "MAY" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode">
- <doc>
- This method sets the channel to use standard transactions. The client must use this
- method at least once on a channel before using the Commit or Rollback methods.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "select-ok" />
- </method>
-
- <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode">
- <doc>
- This method confirms to the client that the channel was successfully set to use
- standard transactions.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "commit" synchronous = "1" index = "20" label = "commit the current transaction">
- <doc>
- This method commits all messages published and acknowledged in the current
- transaction. A new transaction starts immediately after a commit.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "commit-ok" />
- </method>
-
- <method name = "commit-ok" synchronous = "1" index = "21" label = "confirm a successful commit">
- <doc>
- This method confirms to the client that the commit succeeded. Note that if a commit
- fails, the server raises a channel exception.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "rollback" synchronous = "1" index = "30"
- label = "abandon the current transaction">
- <doc>
- This method abandons all messages published and acknowledged in the current
- transaction. A new transaction starts immediately after a rollback.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "rollback-ok" />
- </method>
-
- <method name = "rollback-ok" synchronous = "1" index = "31" label = "confirm successful rollback">
- <doc>
- This method confirms to the client that the rollback succeeded. Note that if an
- rollback fails, the server raises a channel exception.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
- </class>
-
- <!-- == DTX ============================================================== -->
-
- <class name = "dtx" handler = "channel" index = "100" label = "work with distributed transactions">
- <doc>
- Distributed transactions provide so-called "2-phase commit". The AMQP distributed
- transaction model supports the X-Open XA architecture and other distributed transaction
- implementations. The Dtx class assumes that the server has a private communications
- channel (not AMQP) to a distributed transaction coordinator.
- </doc>
-
- <doc type = "grammar">
- dtx = C:SELECT S:SELECT-OK
- C:START S:START-OK
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode">
- <doc>
- This method sets the channel to use distributed transactions. The client must use
- this method at least once on a channel before using the Start method.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <response name = "select-ok" />
- </method>
-
- <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode">
- <doc>
- This method confirms to the client that the channel was successfully set to use
- distributed transactions.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "start" synchronous = "1" index = "20"
- label = "start a new distributed transaction">
- <doc>
- This method starts a new distributed transaction. This must be the first method on a
- new channel that uses the distributed transaction mode, before any methods that
- publish or consume messages.
- </doc>
- <chassis name = "server" implement = "MAY" />
- <response name = "start-ok" />
- <field name = "dtx-identifier" domain = "shortstr" label = "transaction identifier">
- <doc>
- The distributed transaction key. This identifies the transaction so that the
- AMQP server can coordinate with the distributed transaction coordinator.
- </doc>
- <assert check = "notnull" />
- </field>
- </method>
-
- <method name = "start-ok" synchronous = "1" index = "21"
- label = "confirm the start of a new distributed transaction">
- <doc>
- This method confirms to the client that the transaction started. Note that if a
- start fails, the server raises a channel exception.
- </doc>
- <chassis name = "client" implement = "MUST" />
- </method>
- </class>
-
- <!-- == TUNNEL =========================================================== -->
-
- <class name = "tunnel" handler = "tunnel" index = "110" label = "methods for protocol tunneling">
- <doc>
- The tunnel methods are used to send blocks of binary data - which can be serialised AMQP
- methods or other protocol frames - between AMQP peers.
- </doc>
-
- <doc type = "grammar">
- tunnel = C:REQUEST
- / S:REQUEST
- </doc>
-
- <chassis name = "server" implement = "MAY" />
- <chassis name = "client" implement = "MAY" />
-
- <field name = "headers" domain = "table" label = "message header field table" />
- <field name = "proxy-name" domain = "shortstr" label = "identity of tunnelling proxy" />
- <field name = "data-name" domain = "shortstr" label = "name or type of message being tunnelled" />
- <field name = "durable" domain = "octet" label = "message durability indicator" />
- <field name = "broadcast" domain = "octet" label = "message broadcast mode" />
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-
- <method name = "request" content = "1" index = "10" label = "sends a tunnelled method">
- <doc>
- This method tunnels a block of binary data, which can be an encoded
- AMQP method or other data. The binary data is sent as the content for
- the Tunnel.Request method.
- </doc>
- <chassis name = "server" implement = "MUST" />
- <field name = "meta-data" domain = "table" label = "meta data for the tunnelled block">
- <doc>
- This field table holds arbitrary meta-data that the sender needs to
- pass to the recipient.
- </doc>
- </field>
- </method>
- </class>
-</amqp>
diff --git a/gentools/xml-src/cluster-0.9.test.xml b/gentools/xml-src/cluster-0.9.test.xml
deleted file mode 100644
index 142e6c9380..0000000000
--- a/gentools/xml-src/cluster-0.9.test.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0"?>
-<!--
- -
- - 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.
- -
- -->
-
-<amqp major="0" minor="9" port="5672" comment="AMQ protocol 0.80">
-
-<class name = "cluster" index = "101">
-
-<doc>
- An extension that allows brokers to communicate in order to
- provide a clustered service to clients.
-</doc>
-
-<method name = "join" index="10">
- <field name = "broker" type = "shortstr" />
-</method>
-
-<method name = "membership" index="20">
- <field name = "members" type = "longstr" />
-</method>
-
-<method name = "synch" index="30">
-</method>
-
-<method name = "leave" index="40">
- <field name = "broker" type = "shortstr" />
-</method>
-
-<method name = "suspect" index="50">
- <field name = "broker" type = "shortstr" />
-</method>
-
-<method name = "ping" index="60">
- <field name = "broker" type = "shortstr" />
- <field name = "load" type = "long" />
- <field name = "response required" type = "bit" />
-</method>
-
-</class>
-
-</amqp>