From bb2883b9f5cfad0e028a9849ed91e36418a2d0ff Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Tue, 21 Aug 2007 15:51:41 +0000 Subject: Refresh of transitional xml to more closely reflect latest specification Initial execution-result support (not yet handled on c++ client) Generation is now all done through the ruby code (it is a little slower at present I'm afraid, will try to speed it up over the next weeks) git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@568174 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/README | 2 +- cpp/gentools/README | 61 - cpp/gentools/build | 15 - cpp/gentools/build.xml | 34 - .../src/org/apache/qpid/gentools/AmqpClass.java | 151 - .../src/org/apache/qpid/gentools/AmqpClassMap.java | 29 - .../src/org/apache/qpid/gentools/AmqpConstant.java | 205 - .../org/apache/qpid/gentools/AmqpConstantSet.java | 133 - .../src/org/apache/qpid/gentools/AmqpDomain.java | 78 - .../org/apache/qpid/gentools/AmqpDomainMap.java | 119 - .../apache/qpid/gentools/AmqpDomainVersionMap.java | 58 - .../src/org/apache/qpid/gentools/AmqpField.java | 156 - .../src/org/apache/qpid/gentools/AmqpFieldMap.java | 348 -- .../src/org/apache/qpid/gentools/AmqpFlagMap.java | 84 - .../src/org/apache/qpid/gentools/AmqpMethod.java | 204 - .../org/apache/qpid/gentools/AmqpMethodMap.java | 36 - .../src/org/apache/qpid/gentools/AmqpModel.java | 80 - .../apache/qpid/gentools/AmqpOrdinalFieldMap.java | 89 - .../qpid/gentools/AmqpOrdinalVersionMap.java | 72 - .../qpid/gentools/AmqpOverloadedParameterMap.java | 29 - .../apache/qpid/gentools/AmqpParseException.java | 30 - .../qpid/gentools/AmqpTemplateException.java | 30 - .../qpid/gentools/AmqpTypeMappingException.java | 30 - .../src/org/apache/qpid/gentools/AmqpVersion.java | 68 - .../org/apache/qpid/gentools/AmqpVersionSet.java | 74 - .../src/org/apache/qpid/gentools/CppGenerator.java | 1693 -------- .../org/apache/qpid/gentools/DotnetGenerator.java | 339 -- .../src/org/apache/qpid/gentools/Generator.java | 429 -- .../org/apache/qpid/gentools/JavaGenerator.java | 1702 -------- .../apache/qpid/gentools/LanguageConverter.java | 39 - .../src/org/apache/qpid/gentools/Main.java | 347 -- .../src/org/apache/qpid/gentools/NodeAware.java | 46 - .../src/org/apache/qpid/gentools/Printable.java | 28 - .../qpid/gentools/TargetDirectoryException.java | 30 - .../src/org/apache/qpid/gentools/Utils.java | 153 - .../qpid/gentools/VersionConsistencyCheck.java | 26 - .../templ.cpp/AMQP_ClientOperations.h.tmpl | 64 - cpp/gentools/templ.cpp/AMQP_Constants.h.tmpl | 34 - cpp/gentools/templ.cpp/AMQP_HighestVersion.h.tmpl | 42 - .../templ.cpp/AMQP_MethodVersionMap.cpp.tmpl | 62 - .../templ.cpp/AMQP_ServerOperations.h.tmpl | 72 - cpp/gentools/templ.cpp/MethodBodyClass.h.tmpl | 115 - cpp/gentools/templ.java/AmqpConstantsClass.tmpl | 37 - cpp/gentools/templ.java/MethodBodyClass.tmpl | 180 - cpp/gentools/templ.java/MethodRegistryClass.tmpl | 125 - .../templ.java/PropertyContentHeaderClass.tmpl | 207 - .../templ.java/ProtocolVersionListClass.tmpl | 38 - cpp/gentools/xml-src/amqp-0.10.test.xml | 4241 ------------------- cpp/gentools/xml-src/amqp-0.8.test.xml | 3959 ------------------ cpp/gentools/xml-src/amqp-0.9.test.xml | 4282 -------------------- cpp/gentools/xml-src/cluster-0.9.test.xml | 59 - cpp/rubygen/amqpgen.rb | 65 +- cpp/rubygen/cppgen.rb | 31 +- cpp/rubygen/generate | 12 +- cpp/rubygen/samples/Operations.rb | 85 - cpp/rubygen/samples/runme | 18 - cpp/rubygen/templates/InvocationVisitor.rb | 105 + cpp/rubygen/templates/Operations.rb | 108 + cpp/rubygen/templates/Session.rb | 6 +- cpp/rubygen/templates/structs.rb | 345 ++ cpp/src/Makefile.am | 33 +- cpp/src/qpid/broker/BrokerAdapter.cpp | 57 +- cpp/src/qpid/broker/BrokerAdapter.h | 36 +- cpp/src/qpid/broker/BrokerChannel.cpp | 2 +- cpp/src/qpid/broker/BrokerQueue.h | 4 +- cpp/src/qpid/broker/DtxHandlerImpl.cpp | 63 +- cpp/src/qpid/broker/DtxHandlerImpl.h | 22 +- cpp/src/qpid/broker/MessageHandlerImpl.cpp | 20 +- cpp/src/qpid/broker/MessageHandlerImpl.h | 26 +- cpp/src/qpid/broker/SemanticHandler.cpp | 44 +- cpp/src/qpid/broker/SemanticHandler.h | 5 +- cpp/src/qpid/client/ClientChannel.cpp | 22 +- cpp/src/qpid/client/ClientChannel.h | 5 +- cpp/src/qpid/client/Connection.h | 2 +- cpp/src/qpid/client/ExecutionHandler.cpp | 22 +- cpp/src/qpid/client/ExecutionHandler.h | 5 +- cpp/src/qpid/framing/AMQP_HighestVersion.h | 40 + cpp/src/qpid/framing/StructHelper.h | 56 + cpp/src/qpid/framing/amqp_types_full.h | 1 + cpp/src/tests/Blob | Bin 223166 -> 0 bytes cpp/src/tests/Cluster_child.cpp | 2 +- 81 files changed, 977 insertions(+), 20829 deletions(-) delete mode 100644 cpp/gentools/README delete mode 100755 cpp/gentools/build delete mode 100644 cpp/gentools/build.xml delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpClass.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpClassMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpConstant.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpDomain.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpField.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpMethod.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpModel.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpParseException.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpVersion.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/CppGenerator.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/Generator.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/JavaGenerator.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/LanguageConverter.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/Main.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/NodeAware.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/Printable.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/TargetDirectoryException.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/Utils.java delete mode 100644 cpp/gentools/src/org/apache/qpid/gentools/VersionConsistencyCheck.java delete mode 100644 cpp/gentools/templ.cpp/AMQP_ClientOperations.h.tmpl delete mode 100644 cpp/gentools/templ.cpp/AMQP_Constants.h.tmpl delete mode 100644 cpp/gentools/templ.cpp/AMQP_HighestVersion.h.tmpl delete mode 100644 cpp/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl delete mode 100644 cpp/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl delete mode 100644 cpp/gentools/templ.cpp/MethodBodyClass.h.tmpl delete mode 100644 cpp/gentools/templ.java/AmqpConstantsClass.tmpl delete mode 100644 cpp/gentools/templ.java/MethodBodyClass.tmpl delete mode 100644 cpp/gentools/templ.java/MethodRegistryClass.tmpl delete mode 100644 cpp/gentools/templ.java/PropertyContentHeaderClass.tmpl delete mode 100644 cpp/gentools/templ.java/ProtocolVersionListClass.tmpl delete mode 100644 cpp/gentools/xml-src/amqp-0.10.test.xml delete mode 100644 cpp/gentools/xml-src/amqp-0.8.test.xml delete mode 100644 cpp/gentools/xml-src/amqp-0.9.test.xml delete mode 100644 cpp/gentools/xml-src/cluster-0.9.test.xml delete mode 100755 cpp/rubygen/samples/Operations.rb delete mode 100755 cpp/rubygen/samples/runme create mode 100644 cpp/rubygen/templates/InvocationVisitor.rb create mode 100755 cpp/rubygen/templates/Operations.rb create mode 100644 cpp/rubygen/templates/structs.rb create mode 100644 cpp/src/qpid/framing/AMQP_HighestVersion.h create mode 100644 cpp/src/qpid/framing/StructHelper.h delete mode 100755 cpp/src/tests/Blob (limited to 'cpp') diff --git a/cpp/README b/cpp/README index c4cc67f133..35e3630502 100644 --- a/cpp/README +++ b/cpp/README @@ -54,7 +54,7 @@ all of the above plus: * libtool (1.5.22) * doxygen (1.5.1) * graphviz (2.12) - * JDK 5.0 (1.5.0.11) + * ruby 1.8 (1.8.4) === Installing as root === diff --git a/cpp/gentools/README b/cpp/gentools/README deleted file mode 100644 index c4abecc199..0000000000 --- a/cpp/gentools/README +++ /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 (qpid-dev [at] incubator.apache.org). - -Kim van der Riet diff --git a/cpp/gentools/build b/cpp/gentools/build deleted file mode 100755 index ad9827b113..0000000000 --- a/cpp/gentools/build +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -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 org/apache/qpid/gentools/*.java -echo "Done. Try it out..." -java org.apache.qpid.gentools.Main -echo "--------- Building gentools completed ----------" -cd .. diff --git a/cpp/gentools/build.xml b/cpp/gentools/build.xml deleted file mode 100644 index 8fba85bc57..0000000000 --- a/cpp/gentools/build.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpClass.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpClass.java deleted file mode 100644 index 1bc9dc456a..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpClass.java +++ /dev/null @@ -1,151 +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 org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class AmqpClass implements Printable, NodeAware -{ - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpFieldMap fieldMap; - public AmqpMethodMap methodMap; - public String name; - public AmqpOrdinalVersionMap indexMap; - - public AmqpClass(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - fieldMap = new AmqpFieldMap(); - methodMap = new AmqpMethodMap(); - indexMap = new AmqpOrdinalVersionMap(); - } - - public boolean addFromNode(Node classNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - int index = Utils.getNamedIntegerAttribute(classNode, "index"); - AmqpVersionSet indexVersionSet = indexMap.get(index); - if (indexVersionSet != null) - indexVersionSet.add(version); - else - { - indexVersionSet = new AmqpVersionSet(); - indexVersionSet.add(version); - indexMap.put(index, indexVersionSet); - } - NodeList nList = classNode.getChildNodes(); - int fieldCntr = fieldMap.size(); - for (int i=0; i -{ - -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpConstant.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpConstant.java deleted file mode 100644 index 6ccd2dbf99..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpConstant.java +++ /dev/null @@ -1,205 +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 <constant> declaration within the AMQP specification. - * Currently, only integer values exist within the specification, however looking forward - * to other possible types in the future, string and double types are also supported. - * - * The <constant> declaration in the specification contains only two attributes: - * name and value. - * - * The value of the constant is mapped against the version(s) for which the name is defined. - * This allows for a change in the value rather than the name only from one version to the next. - */ -@SuppressWarnings("serial") -public class AmqpConstant extends TreeMap - implements Printable, VersionConsistencyCheck, Comparable -{ - /** - * Constant name as defined by the name attribute of the <constant> declaration. - */ - protected String name; - - /** - * Set of versions for which this constant name is defined. - */ - protected AmqpVersionSet versionSet; - - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, String value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(value, valueVersionSet); - } - - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, int value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(String.valueOf(value), valueVersionSet); - } - - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, double value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(String.valueOf(value), valueVersionSet); - } - - /** - * Get the name of this constant. - * @return Name of this constant, being the name attribute of the <constant> declaration - * represented by this class. - */ - 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 <constant> 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 \"" + name + - "\" for version " + version.toString() + "."); - } - - /** - * Get the value of this constant as an integer. - * @param version AMQP version for which this value is required. - * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. - * @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 <constant> 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 = name.compareTo(other.name); - if (res != 0) - return res; - return versionSet.compareTo(other.versionSet); - } - - /* (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] " + name + " = \"" + firstKey() + "\" " + versionSet); - } - else - { - out.println(margin + tab + "[C] " + name + ": " + versionSet); - for (String thisValue : keySet()) - { - out.println(margin + tab + tab + "= \"" + thisValue + "\" " + get(thisValue)); - } - } - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java deleted file mode 100644 index 7b38f5cf3c..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java +++ /dev/null @@ -1,133 +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; - -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -/** - * @author kpvdr - * This class implements a set collection for {@link #AmqpConstant AmqpConstant} objects, being the collection - * of constants accumulated from various AMQP specification files processed. Each name occurs once only in the set. - * The {@link #AmqpConstant AmqpConstant} objects (derived from {@link java.util#TreeMap TreeMap}) keep track of - * the value and version(s) assigned to this name. - */ -@SuppressWarnings("serial") -public class AmqpConstantSet extends TreeSet implements Printable, NodeAware, Comparable -{ - public LanguageConverter converter; - - public AmqpConstantSet(LanguageConverter converter) - { - this.converter = converter; - this.converter.setConstantSet(this); - } - - /* (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 - { - NodeList nodeList = node.getChildNodes(); - for (int i=0; i cItr = iterator(); - while (cItr.hasNext() && !foundName) - { - AmqpConstant thisConstant = cItr.next(); - if (name.compareTo(thisConstant.name) == 0) - { - foundName = true; - thisConstant.versionSet.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) - { - 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 : this) - { - 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 cItr = iterator(); - Iterator 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; - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomain.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomain.java deleted file mode 100644 index 4796f31fb3..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomain.java +++ /dev/null @@ -1,78 +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 implements Printable -{ - public String domainName; - - public AmqpDomain(String domainName) - { - this.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 + domainName + ":"); - - for (String thisDomainType : keySet()) - { - AmqpVersionSet vs = get(thisDomainType); - out.println(margin + tab + thisDomainType + " : " + vs.toString()); - } - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java deleted file mode 100644 index 7e2974a444..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java +++ /dev/null @@ -1,119 +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; - -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -@SuppressWarnings("serial") -public class AmqpDomainMap extends TreeMap implements Printable, NodeAware -{ - public LanguageConverter converter; - - public AmqpDomainMap(LanguageConverter converter) - { - this.converter = converter; - this.converter.setDomainMap(this); - } - - public boolean addFromNode(Node n, int o, AmqpVersion v) - throws AmqpParseException, AmqpTypeMappingException - { - NodeList nl = n.getChildNodes(); - for (int i=0; i for all domains - if (c.getNodeName().compareTo(Utils.ELEMENT_DOMAIN) == 0) - { - String domainName = converter.prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); - String type = Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE); - AmqpDomain thisDomain = get(domainName); - if (thisDomain == null) - { - thisDomain = new AmqpDomain(domainName); - put(domainName, thisDomain); - } - thisDomain.addDomain(type, v); - } - // Version(s) 0.8 and earlier use for all complex domains and use - // attribute for simple types. Add these simple types to - // domain list - but beware of duplicates! - else if (c.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) - { - try - { - String type = converter.prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE)); - AmqpDomain thisDomain = get(type); - if (thisDomain == null) - { - thisDomain = new AmqpDomain(type); - put(type, thisDomain); - } - if (!thisDomain.hasVersion(type, v)) - thisDomain.addDomain(type, v); - } - catch (AmqpParseException e) {} // Ignore fields without type attribute - } - else if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0 || - c.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0) - { - addFromNode(c, 0, v); - } - } - return true; - } - - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - AmqpDomain domainType = get(domainName); - // For AMQP 8.0, primitive types were not described as domains, so - // return itself as the type. - if (domainType == null) - { - return domainName; - } - try - { - return domainType.getDomainType(version); - } - catch (AmqpTypeMappingException e) - { - throw new AmqpTypeMappingException("Unable to find domain type for domain \"" + domainName + - "\" version " + version + "."); - } - } - - - public void print(PrintStream out, int marginSize, int tabSize) - { - out.println(Utils.createSpaces(marginSize) + "Domain Map:"); - for (String thisDomainName : keySet()) - { - AmqpDomain domain = get(thisDomainName); - domain.print(out, marginSize + tabSize, tabSize); - } - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java deleted file mode 100644 index f91d98bfe7..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java +++ /dev/null @@ -1,58 +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 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 removeList = new ArrayList(); - 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/cpp/gentools/src/org/apache/qpid/gentools/AmqpField.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpField.java deleted file mode 100644 index e1177e0154..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpField.java +++ /dev/null @@ -1,156 +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.ArrayList; - -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class AmqpField implements Printable, NodeAware, VersionConsistencyCheck -{ - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpDomainVersionMap domainMap; - public AmqpOrdinalVersionMap ordinalMap; - public String name; - - public AmqpField(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - domainMap = new AmqpDomainVersionMap(); - ordinalMap = new AmqpOrdinalVersionMap(); - } - - public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - String domainType; - // Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields. - try - { - domainType = converter.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN)); - } - catch (AmqpParseException e) - { - domainType = converter.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE)); - } - AmqpVersionSet thisVersionList = domainMap.get(domainType); - if (thisVersionList == null) // First time, create new entry - { - thisVersionList = new AmqpVersionSet(); - domainMap.put(domainType, thisVersionList); - } - thisVersionList.add(version); - thisVersionList = ordinalMap.get(ordinal); - if (thisVersionList == null) // First time, create new entry - { - thisVersionList = new AmqpVersionSet(); - ordinalMap.put(ordinal, thisVersionList); - } - thisVersionList.add(version); - NodeList nList = fieldNode.getChildNodes(); - for (int i=0; i codeTypeList = new ArrayList(); - for (String thisDomainName : domainMap.keySet()) - { - AmqpVersionSet versionSet = domainMap.get(thisDomainName); - String codeType = converter.getGeneratedType(thisDomainName, versionSet.first()); - if (!codeTypeList.contains(codeType)) - codeTypeList.add(codeType); - } - return codeTypeList.size() == 1; - } - - public boolean isConsistent(Generator generator) - throws AmqpTypeMappingException - { - if (!isCodeTypeConsistent(generator)) - return false; - if (ordinalMap.size() != 1) - return false; - // Since the various doamin names map to the same code type, add the version occurrences - // across all domains to see we have all possible versions covered - int vCntr = 0; - for (String thisDomainName : domainMap.keySet()) - { - vCntr += domainMap.get(thisDomainName).size(); - } - return vCntr == generator.globalVersionSet.size(); - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - String margin = Utils.createSpaces(marginSize); - out.println(margin + "[F] " + name + ": " + versionSet); - - for (Integer thisOrdinal : ordinalMap.keySet()) - { - AmqpVersionSet versionList = ordinalMap.get(thisOrdinal); - out.println(margin + " [O] " + thisOrdinal + " : " + versionList.toString()); - } - - for (String thisDomainName : domainMap.keySet()) - { - AmqpVersionSet versionList = domainMap.get(thisDomainName); - out.println(margin + " [D] " + thisDomainName + " : " + versionList.toString()); - } - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (!versionSet.equals(globalVersionSet)) - return false; - if (!domainMap.isVersionConsistent(globalVersionSet)) - return false; - if (!ordinalMap.isVersionConsistent(globalVersionSet)) - return false; - return true; - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java deleted file mode 100644 index c91ec3d623..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java +++ /dev/null @@ -1,348 +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.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.TreeMap; - -@SuppressWarnings("serial") -public class AmqpFieldMap extends TreeMap implements VersionConsistencyCheck -{ - public void removeVersion(AmqpVersion version) - { - String[] fieldNameArray = new String[size()]; - keySet().toArray(fieldNameArray); - for (String fieldName : fieldNameArray) - { - get(fieldName).removeVersion(version); - remove(fieldName); - } - } - - public AmqpFieldMap getFieldMapForOrdinal(int ordinal) - { - AmqpFieldMap newMap = new AmqpFieldMap(); - for (String thisFieldName: keySet()) - { - AmqpField field = get(thisFieldName); - TreeMap ordinalMap = field.ordinalMap; - AmqpVersionSet ordinalVersions = ordinalMap.get(ordinal); - if (ordinalVersions != null) - { - newMap.put(field.name, field); - } - } - return newMap; - } - - public AmqpOrdinalFieldMap getMapForVersion(AmqpVersion version, boolean codeTypeFlag, - LanguageConverter converter) - throws AmqpTypeMappingException - { - // TODO: REVIEW THIS! There may be a bug here that affects C++ generation (only with >1 version)... - // If version == null (a common scenario) then the version map is built up on the - // basis of first found item, and ignores other version variations. - // This should probably be disallowed by throwing an NPE, as AmqpOrdinalFieldMap cannot - // represent these possibilities. - // *OR* - // Change the structure of AmqpOrdianlFieldMap to allow for the various combinations that - // will result from version variation - but that is what AmqpFieldMap is... :-$ - AmqpOrdinalFieldMap ordinalFieldMap = new AmqpOrdinalFieldMap(); - for (String thisFieldName: keySet()) - { - AmqpField field = get(thisFieldName); - if (version == null || field.versionSet.contains(version)) - { - // 1. Search for domain name in field domain map with version that matches - String domain = ""; - boolean dFound = false; - for (String thisDomainName : field.domainMap.keySet()) - { - domain = thisDomainName; - AmqpVersionSet versionSet = field.domainMap.get(domain); - if (version == null || versionSet.contains(version)) - { - if (codeTypeFlag) - domain = converter.getGeneratedType(domain, version); - dFound = true; - } - } - - // 2. Search for ordinal in field ordianl map with version that matches - int ordinal = -1; - boolean oFound = false; - for (Integer thisOrdinal : field.ordinalMap.keySet()) - { - ordinal = thisOrdinal; - AmqpVersionSet versionSet = field.ordinalMap.get(ordinal); - if (version == null || versionSet.contains(version)) - oFound = true; - } - - if (dFound && oFound) - { - String[] fieldDomainPair = {field.name, domain}; - ordinalFieldMap.put(ordinal, fieldDomainPair); - } - } - } - return ordinalFieldMap; - } - - public boolean isDomainConsistent(Generator generator, AmqpVersionSet versionSet) - throws AmqpTypeMappingException - { - if (size() != 1) // Only one field for this ordinal - return false; - return get(firstKey()).isConsistent(generator); - } - - public int getNumFields(AmqpVersion version) - { - int fCntr = 0; - for (String thisFieldName : keySet()) - { - AmqpField field = get(thisFieldName); - if (field.versionSet.contains(version)) - fCntr++; - } - return fCntr; - } - - public String parseFieldMap(Method commonGenerateMethod, Method mangledGenerateMethod, - int indentSize, int tabSize, LanguageConverter converter) - throws AmqpTypeMappingException, IllegalAccessException, InvocationTargetException - { - String indent = Utils.createSpaces(indentSize); - String cr = Utils.lineSeparator; - StringBuffer sb = new StringBuffer(); - - if (commonGenerateMethod == null) - { - // Generate warnings in code if required methods are null. - sb.append(indent + "/*********************************************************" + cr); - sb.append(indent + " * WARNING: Generated code could be missing." + cr); - sb.append(indent + " * In call to parseFieldMap(), generation method was null." + cr); - sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); - sb.append(indent + " *********************************************************/" + cr); - } - - Iterator itr = keySet().iterator(); - while (itr.hasNext()) - { - String fieldName = itr.next(); - AmqpField field = get(fieldName); - if (field.isCodeTypeConsistent(converter)) - { - // All versions identical - Common declaration - String domainName = field.domainMap.firstKey(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = converter.getGeneratedType(domainName, versionSet.first()); - if (commonGenerateMethod != null) - sb.append(commonGenerateMethod.invoke(converter, codeType, field, versionSet, - indentSize, tabSize, itr.hasNext())); - } - else if (mangledGenerateMethod != null) // Version-mangled - { - sb.append(mangledGenerateMethod.invoke(converter, field, indentSize, tabSize, - itr.hasNext())); - } - } - return sb.toString(); - } - - public String parseFieldMapOrdinally(Method generateMethod, Method bitGenerateMethod, - int indentSize, int tabSize, Generator codeGenerator) - throws AmqpTypeMappingException, IllegalAccessException, InvocationTargetException - { - String indent = Utils.createSpaces(indentSize); - String cr = Utils.lineSeparator; - StringBuffer sb = new StringBuffer(); - - // Generate warnings in code if required methods are null. - if (generateMethod == null || bitGenerateMethod == null) - { - sb.append(indent + "/***********************************************" + cr); - sb.append(indent + " * WARNING: In call to parseFieldMapOrdinally():" + cr); - if (generateMethod == null) - sb.append(indent + " * => generateMethod is null." + cr); - if (bitGenerateMethod == null) - sb.append(indent + " * => bitGenerateMethod is null." + cr); - sb.append(indent + " * Generated code could be missing." + cr); - sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); - sb.append(indent + " ***********************************************/" + cr); - } - - /* We must process elements in ordinal order because adjacent booleans (bits) - * must be combined into a single byte (in groups of up to 8). Start with shared - * declarations until an ordinal divergence is found. (For most methods where - * there is no difference between versions, this will simplify the generated - * code. */ - - ArrayList bitFieldList = new ArrayList(); - boolean ordinalDivergenceFlag = false; - int ordinal = 0; - while (ordinal < size() && !ordinalDivergenceFlag) - { - /* Since the getFieldMapOrdinal() function may map more than one Field to - * an ordinal, the number of ordinals may be less than the total number of - * fields in the fieldMap. Check for empty fieldmaps... */ - AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(ordinal); - if (ordinalFieldMap.size() > 0) - { - if (ordinalFieldMap.isDomainConsistent(codeGenerator, codeGenerator.globalVersionSet)) - { - String fieldName = ordinalFieldMap.firstKey(); - String domain = ordinalFieldMap.get(fieldName).domainMap.firstKey(); - String domainType = codeGenerator.getDomainType(domain, - codeGenerator.globalVersionSet.first()); - if (domainType.compareTo("bit") == 0) - bitFieldList.add(fieldName); - else if (bitFieldList.size() > 0) - { - // End of bit types - handle deferred bit type generation - if (bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, bitFieldList, ordinal, - indentSize, tabSize)); - bitFieldList.clear(); - } - if (!ordinalDivergenceFlag) - { - // Defer generation of bit types until all adjacent bits have been - // accounted for. - if (bitFieldList.size() == 0 && generateMethod != null) - sb.append(generateMethod.invoke(codeGenerator, domainType, fieldName, ordinal, - indentSize, tabSize)); - } - ordinal++; - } - else - { - ordinalDivergenceFlag = true; - } - } - } - - // Check if there is still more to do under a version-specific breakout - if (ordinalDivergenceFlag && ordinal< size()) - { - // 1. Cycle through all versions in order, create outer if(version) structure - AmqpVersion[] versionArray = new AmqpVersion[codeGenerator.globalVersionSet.size()]; - codeGenerator.globalVersionSet.toArray(versionArray); - for (int v=0; v 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 bitFieldList2 = new ArrayList(bitFieldList); - for (int o = ordinal; o 0) - { - // 3. Cycle through each of the fields that have this ordinal. - Iterator i = ordinalFieldMap.keySet().iterator(); - while (i.hasNext()) - { - String fieldName = i.next(); - AmqpField field = ordinalFieldMap.get(fieldName); - - // 4. Some fields may have more than one ordinal - match by both - // ordinal and version. - Iterator j = field.ordinalMap.keySet().iterator(); - while (j.hasNext()) - { - int thisOrdinal = j.next(); - AmqpVersionSet v1 = field.ordinalMap.get(thisOrdinal); - if (thisOrdinal == o && v1.contains(versionArray[v])) - { - // 5. Now get the domain for this version - int domainCntr = 0; - Iterator k = field.domainMap.keySet().iterator(); - while (k.hasNext()) - { - // Mangle domain-divergent field names - String mangledFieldName = fieldName; - if (field.domainMap.size() > 1) - mangledFieldName += "_" + (domainCntr++); - String domainName = k.next(); - AmqpVersionSet v2 = field.domainMap.get(domainName); - if (v2.contains(versionArray[v])) - { - // 6. (Finally!!) write the declaration - String domainType = codeGenerator.getDomainType(domainName, - versionArray[v]); - if (domainType.compareTo("bit") == 0) - bitFieldList2.add(mangledFieldName); - else if (bitFieldList2.size() > 0) - { - // End of bit types - handle deferred bit type generation - if (bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, - bitFieldList2, o, indentSize + tabSize, - tabSize)); - bitFieldList2.clear(); - } - // Defer generation of bit types until all adjacent bits have - // been accounted for. - if (bitFieldList2.size() == 0 && generateMethod != null) - sb.append(generateMethod.invoke(codeGenerator, domainType, - mangledFieldName, o, indentSize + tabSize, tabSize)); - } - } - } - } - } - } - } - // Check for remaining deferred bits - if (bitFieldList2.size() > 0 && bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, bitFieldList2, size(), - indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - } - } - // Check for remaining deferred bits - else if (bitFieldList.size() > 0 && bitGenerateMethod != null) - sb.append(bitGenerateMethod.invoke(codeGenerator, bitFieldList, size(), - indentSize, tabSize)); - return sb.toString(); - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - for (String thisFieldName : keySet()) - { - AmqpField field = get(thisFieldName); - if (!field.isVersionConsistent(globalVersionSet)) - return false; - } - return true; - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java deleted file mode 100644 index 3f86326ce2..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java +++ /dev/null @@ -1,84 +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 implements VersionConsistencyCheck -{ - public boolean isSet() - { - return containsKey(true); - } - - public boolean isSet(AmqpVersion version) - { - return containsKey(true) && get(true).contains(version); - } - - public void setFlagForVersion(boolean flag, AmqpVersion version) { - if (get(flag) == null) { - put(flag, new AmqpVersionSet(version)); - } else { - get(flag).add(version); - } - } - - 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 removeList = new ArrayList(); - 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/cpp/gentools/src/org/apache/qpid/gentools/AmqpMethod.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpMethod.java deleted file mode 100644 index f00bb5fef8..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpMethod.java +++ /dev/null @@ -1,204 +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 org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Element; - -public class AmqpMethod implements Printable, NodeAware, VersionConsistencyCheck -{ - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpFieldMap fieldMap; - public String name; - public AmqpOrdinalVersionMap indexMap; - public AmqpFlagMap clientMethodFlagMap; // Method called on client ( in XML) - public AmqpFlagMap serverMethodFlagMap; // Method called on server ( in XML) - public boolean content; - - public AmqpMethod(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - fieldMap = new AmqpFieldMap(); - indexMap = new AmqpOrdinalVersionMap(); - clientMethodFlagMap = new AmqpFlagMap(); - serverMethodFlagMap = new AmqpFlagMap(); - } - - /** Check if this method is named as a response by any other method in the class. */ - public void checkForResponse(Element methodElement, AmqpVersion version) { - Element clazz = (Element)methodElement.getParentNode(); - String methodName = methodElement.getAttribute("name"); - NodeList methods = clazz.getElementsByTagName("method"); - for (int i=0; i -{ - public void removeVersion(AmqpVersion version) - { - for (String methodName : keySet()) - { - get(methodName).removeVersion(version); - } - } - -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpModel.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpModel.java deleted file mode 100644 index 721247a4b2..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpModel.java +++ /dev/null @@ -1,80 +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 org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -public class AmqpModel implements Printable, NodeAware -{ - public LanguageConverter converter; - public AmqpClassMap classMap; - - public AmqpModel(LanguageConverter converter) - { - this.converter = converter; - this.converter.setModel(this); - classMap = new AmqpClassMap(); - } - - public boolean addFromNode(Node n, int o, AmqpVersion v) - throws AmqpParseException, AmqpTypeMappingException - { - NodeList nList = n.getChildNodes(); - int eCntr = 0; - for (int i=0; i implements Comparable -{ - protected static final int FIELD_DOMAIN = 1; - protected boolean codeTypeFlag = false; - - public int compareTo(Object obj) - { - AmqpOrdinalFieldMap o = (AmqpOrdinalFieldMap)obj; - Set thisKeySet = keySet(); - Set 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 itr = thisKeySet.iterator(); - Iterator 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 itr = thisKeySet.iterator(); - Iterator 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 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 removeList = new ArrayList(); - 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/cpp/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpOverloadedParameterMap.java deleted file mode 100644 index 10978d0e4a..0000000000 --- a/cpp/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 -{ - -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpParseException.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpParseException.java deleted file mode 100644 index 4d9f495390..0000000000 --- a/cpp/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 Exception -{ - public AmqpParseException(String msg) - { - super(msg); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java deleted file mode 100644 index b1e6f3d712..0000000000 --- a/cpp/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 Exception -{ - public AmqpTemplateException(String msg) - { - super(msg); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java deleted file mode 100644 index 1053543fdd..0000000000 --- a/cpp/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 Exception -{ - public AmqpTypeMappingException(String msg) - { - super(msg); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpVersion.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpVersion.java deleted file mode 100644 index 579d8e28b2..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpVersion.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 AmqpVersion implements Comparable -{ - private int major; - private int minor; - - public AmqpVersion(int major, int minor) - { - this.major = major; - this.minor = minor; - } - - public AmqpVersion(AmqpVersion version) - { - this.major = version.major; - this.minor = version.minor; - } - - public int getMajor() - { - return major; - } - - public int getMinor() - { - return minor; - } - - public int compareTo(AmqpVersion v) - { - if (major != v.major) - return major - v.major; - if (minor != v.minor) - return minor - v.minor; - return 0; - } - - public String namespace() - { - return "ver_" + major + "_" + minor; - } - - public String toString() - { - return major + "-" + minor; - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java b/cpp/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java deleted file mode 100644 index 4406893cbb..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java +++ /dev/null @@ -1,74 +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.ArrayList; -import java.util.Iterator; -import java.util.TreeSet; - -@SuppressWarnings("serial") -public class AmqpVersionSet extends TreeSet implements Printable, Comparable -{ - 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.lineSeparator); - } - - public int compareTo(AmqpVersionSet other) - { - int res = size() - other.size(); - if (res != 0) - return res; - Iterator vItr = iterator(); - Iterator 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/cpp/gentools/src/org/apache/qpid/gentools/CppGenerator.java b/cpp/gentools/src/org/apache/qpid/gentools/CppGenerator.java deleted file mode 100644 index 114e3308d3..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/CppGenerator.java +++ /dev/null @@ -1,1693 +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.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.TreeMap; - -public class CppGenerator extends Generator -{ - protected static final String versionNamespaceStartToken = "${version_namespace_start}"; - protected static final String versionNamespaceEndToken = "${version_namespace_end}"; - - // TODO: Move this to parent class - protected static final int FIELD_NAME = 0; - protected static final int FIELD_CODE_TYPE = 1; - - /** - * 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 typeMap = new TreeMap(); - - public CppGenerator(AmqpVersionSet versionList) - { - super(versionList); - 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 - - //some 0-10 types: - - typeMap.put("uuid", new DomainInfo( - "string", // type - "4 + #.length()", // size - "buffer.putLongString(#)", // encodeExpression - "buffer.getLongString(#)")); // decodeExpression - - typeMap.put("rfc1982-long-set", new DomainInfo( - "SequenceNumberSet", // type - "#.encodedSize()", // size - "#.encode(buffer)", // encodeExpression - "#.decode(buffer)")); // 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 getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - if (version == null) - version = globalVersionSet.first(); - return globalDomainMap.getDomainType(domainName, version); - } - - public String getGeneratedType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - String domainType = getDomainType(domainName, version); - if (domainType == null) - { - throw new AmqpTypeMappingException("Domain type \"" + domainName + - "\" not found in C++ typemap."); - } - 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) - { - StringBuffer sb = new StringBuffer(filenameTemplate); - if (thisClass != null) - replaceToken(sb, "${CLASS}", thisClass.name); - if (method != null) - replaceToken(sb, "${METHOD}", method.name); - if (field != null) - replaceToken(sb, "${FIELD}", field.name); - return sb.toString(); - } - - @Override - protected void processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[templateStringIndex]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null); - boolean templateProcessedFlag = false; - - // If method is not version consistent, create a namespace for each version - // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken - // once for each namespace. - if (method != null) - { - if (!method.isVersionConsistent(globalVersionSet)) - { - int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken); - int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) + - versionNamespaceEndToken.length(); - if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 && - namespaceStartIndex <= namespaceEndIndex) - { - String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + cr; - sb.delete(namespaceStartIndex, namespaceEndIndex); - for (AmqpVersion v : method.versionSet) - { - StringBuffer nssb = new StringBuffer(namespaceSpan); - processTemplate(nssb, thisClass, method, null, template[templateFileNameIndex], v); - sb.insert(namespaceStartIndex, nssb); - } - // Process all tokens *not* within the namespace span prior to inserting namespaces - processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); - } - templateProcessedFlag = true; - } - } - // Remove any remaining namespace tags - int nsTokenIndex = sb.indexOf(versionNamespaceStartToken); - while (nsTokenIndex > 0) - { - sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length()); - nsTokenIndex = sb.indexOf(versionNamespaceStartToken); - } - nsTokenIndex = sb.indexOf(versionNamespaceEndToken); - while (nsTokenIndex > 0) - { - sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length()); - nsTokenIndex = sb.indexOf(versionNamespaceEndToken); - } - - if (!templateProcessedFlag) - { - processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); - } - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, AmqpMethod method, - AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[templateStringIndex]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, - AmqpField field, String templateFileName, AmqpVersion version) - throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException - { - try { processAllLists(sb, thisClass, method, version); } - catch (AmqpTemplateException e) - { - System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, version); } - catch (AmqpTemplateException e) - { - System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); - } - } - - @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - if (token.compareTo("${GENERATOR}") == 0) - return generatorInfo; - if (token.compareTo("${CLASS}") == 0 && thisClass != null) - return thisClass.name; - if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) - { - if (version == null) - return String.valueOf(thisClass.indexMap.firstKey()); - return getIndex(thisClass.indexMap, version); - } - if (token.compareTo("${METHOD}") == 0 && method != null) - return method.name; - if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) - { - if (version == null) - return String.valueOf(method.indexMap.firstKey()); - return getIndex(method.indexMap, version); - } - if (token.compareTo("${FIELD}") == 0 && field != null) - return field.name; - if (token.equals(versionNamespaceStartToken) && version != null) - return "namespace " + version.namespace() + cr + "{"; - if (token.equals(versionNamespaceEndToken) && version != null) - return "} // namespace " + version.namespace(); - if (token.equals("${mb_constructor_with_initializers}")) - return generateConstructor(thisClass, method, version, 4, 4); - if (token.equals("${mb_server_operation_invoke}")) - return generateServerOperationsInvoke(thisClass, method, version, 4, 4); - if (token.equals("${mb_server_operation_invoke2}")) - return generateServerOperationsInvoke2(thisClass, method, version, 4, 4); - if (token.equals("${mb_buffer_param}")) - return method.fieldMap.size() > 0 ? " buffer" : "/*buffer*/"; - if (token.equals("${hv_latest_major}")) - return String.valueOf(globalVersionSet.last().getMajor()); - if (token.equals("${hv_latest_minor}")) - return String.valueOf(globalVersionSet.last().getMinor()); - if (token.equals("${mb_base_class}")) - return baseClass(method, version); - - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - private String baseClass(AmqpMethod method, AmqpVersion version) { - return "AMQMethodBody"; - } - - @Override - protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpModel model) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // ClientOperations.h - if (token.compareTo("${coh_method_handler_get_method}") == 0) - { - codeSnippet = generateOpsMethodHandlerGetMethods(model, false, 4); - } - else if (token.compareTo("${coh_inner_class}") == 0) - { - codeSnippet = generateOpsInnerClasses(model, false, 4, 4); - } - - // ServerOperations.h - else if (token.compareTo("${soh_method_handler_get_method}") == 0) - { - codeSnippet = generateOpsMethodHandlerGetMethods(model, true, 4); - } - else if (token.compareTo("${soh_inner_class}") == 0) - { - codeSnippet = generateOpsInnerClasses(model, true, 4, 4); - } - - // ClientProxy.h/cpp - else if (token.compareTo("${cph_inner_class_instance}") == 0) - { - codeSnippet = generateProxyInnerClassInstances(model, false, 4); - } - else if (token.compareTo("${cph_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodDecls(model, false, 4); - } - else if (token.compareTo("${cph_inner_class_defn}") == 0) - { - codeSnippet = generateProxyInnerClassDeclarations(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 = generateProxyInnerClassDeclarations(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) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - 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) - throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, - InvocationTargetException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - if (token.equals("${mb_field_declaration}") ) - codeSnippet = generateFieldDeclarations(fieldMap, version, 4); - else if (token.equals("${mb_field_get_method}") ) - codeSnippet = generateFieldGetMethods(fieldMap, version, 4); - else if (token.equals("${mb_field_print}") ) - codeSnippet = generatePrintMethodContents(fieldMap, version, 8); - else if (token.equals("${mb_body_size}") ) - codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8); - else if (token.equals("${mb_encode}") ) - codeSnippet = generateEncodeMethodContents(fieldMap, version, 8); - else if (token.equals("${mb_decode}") ) - codeSnippet = generateDecodeMethodContents(fieldMap, version, 8); - else // Oops! - throw new AmqpTemplateException("Template token " + token + " unknown."); - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) - throws AmqpTemplateException, AmqpTypeMappingException - { - 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) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - for (AmqpConstant thisConstant : constantSet) - { - if (thisConstant.isVersionConsistent(globalVersionSet)) - { - // return a constant - String value = thisConstant.firstKey(); - sb.append(indent + "static const char* " + thisConstant.name + "() { return \"" + - thisConstant.firstKey() + "\"; }" + cr); - if (Utils.containsOnlyDigits(value)) - { - sb.append(indent + "static int " + thisConstant.name + "AsInt() { return " + - thisConstant.firstKey() + "; }" + cr); - } - if (Utils.containsOnlyDigitsAndDecimal(value)) - { - sb.append(indent + "static double " + thisConstant.name + "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) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + methodReturnType + " " + constant.name + methodNameSuffix + - "() const" + cr); - sb.append(indent + "{" + cr); - 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.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); - } - else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(thisValue)) - { - sb.append(generateConstantDeclarationException(constant.name, 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.name + - "\\\" is undefined for AMQP version \" <<" + cr); - sb.append(indent + tab + tab + tab + "version.toString() << \".\";" + cr); - sb.append(indent + tab + tab + "throw ProtocolVersionException(ss.str());" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + "}" + cr); - return sb.toString(); - } - - 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.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - // Only generate for this class if there is at least one method of the - // required chassis (server/client flag). - boolean chassisFoundFlag = false; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - chassisFoundFlag = true; - } - if (chassisFoundFlag) - { - sb.append(indent + "virtual AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + - thisClass.name + "Handler* get" + thisClass.name + "Handler() = 0;" + cr); - } - } - return sb.toString(); - } - - protected String generateOpsInnerClasses(AmqpModel model, boolean serverFlag, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String handlerClassName = thisClass.name + "Handler"; - if (!first) - sb.append(cr); - sb.append(indent + "// ==================== class " + handlerClassName + - " ====================" + cr); - sb.append(indent + "class " + handlerClassName + " : public virtual Invocable"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "// Constructors and destructors" + cr); - sb.append(indent + "public:" + cr); - sb.append(indent + tab + handlerClassName + "(){};\n"); - sb.append(indent + tab + "virtual ~" + handlerClassName + "() {}" + cr); - sb.append(cr); - sb.append(indent + tab + "// Protocol methods" + cr); - sb.append(cr); - sb.append(generateInnerClassMethods(thisClass, serverFlag, true, indentSize + tabSize, tabSize)); - sb.append(indent + "}; // class " + handlerClassName + cr); - first = false; - } - return sb.toString(); - } - - protected String generateInnerClassMethods(AmqpClass thisClass, boolean serverFlag, - boolean abstractMethodFlag, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + (abstractMethodFlag ? "Operations" : "Proxy"); - boolean first = true; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String returnType = "void"; - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - { - String methodName = parseForReservedWords(method.name, outerClassName + "." + thisClass.name); - AmqpOverloadedParameterMap overloadededParameterMap = - method.getOverloadedParameterLists(thisClass.versionSet, this); - for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) - { - AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); - if (!first) sb.append(cr); - sb.append(indent + "virtual "+returnType+" "+ methodName + "("); - - if (abstractMethodFlag && isSpecialCase(thisClass.name, method.name)) { - sb.append("const AMQMethodBody& context"); - } else { - sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5*tabSize), false, true, true)); - } - - sb.append(" )"); - if (abstractMethodFlag) - sb.append(" = 0"); - sb.append(";"); - if (versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + versionSet); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - // Methods used for generation of code snippets for Server/ClientProxy class generation - - 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.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - sb.append(indent + outerClassName + "::" + thisClass.name + "Handler* " + - thisClass.name + "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.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - sb.append(indent + "virtual " + outerClassName + "::" + thisClass.name + "Handler* get" + - thisClass.name + "Handler() { return &" + Utils.firstLower(thisClass.name) + ";}" + cr); - } - return sb.toString(); - } - - public String proxyInstanceName(AmqpClass inner, String outer) { - return parseForReservedWords(Utils.firstLower(inner.name), outer) - + "Proxy"; - } - - protected String generateProxyInnerClassInstances(AmqpModel model, boolean serverFlag, - int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = proxyOuterClassName(serverFlag); - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = parseForReservedWords(thisClass.name, null); - sb.append(indent + className + " " + - proxyInstanceName(thisClass, outerClassName) + ";"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassGetMethodDecls(AmqpModel model, boolean serverFlag, - int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = parseForReservedWords(thisClass.name, proxyOuterClassName(serverFlag)); - sb.append(indent + className + "& get" + className + "();"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - } - return sb.toString(); - } - - private String proxyOuterClassName(boolean serverFlag) { - return "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - } - - protected String generateProxyInnerClassDeclarations(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = thisClass.name; - if (!first) - sb.append(cr); - sb.append(indent + "// ==================== class " + className + - " ====================" + cr); - sb.append(indent + "class " + className); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(indent + "private:" + cr); - sb.append(indent + tab + "ChannelAdapter& channel;" + 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 + "(ChannelAdapter& ch) : " + cr); - sb.append(indent + tab + tab + "channel(ch) {}" + cr); - sb.append(indent + tab + "virtual ~" + className + "() {}" + cr); - sb.append(cr); - sb.append(indent + tab + "static "+className+"& get(" + proxyOuterClassName(serverFlag)+"& proxy) { return proxy.get"+className+"();}\n\n"); - sb.append(indent + tab + "// set for response correlation" + 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 indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - Iterator cItr = model.classMap.keySet().iterator(); - while (cItr.hasNext()) - { - AmqpClass thisClass = model.classMap.get(cItr.next()); - sb.append(",\n"); - sb.append(indent + proxyInstanceName(thisClass, proxyOuterClassName(serverFlag)) - + "(channel)"); - } - sb.append("\n"); - return sb.toString(); - } - - protected String generateProxyInnerClassGetMethodImpls(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = proxyOuterClassName(serverFlag); - Iterator cItr = model.classMap.keySet().iterator(); - while (cItr.hasNext()) - { - AmqpClass thisClass = model.classMap.get(cItr.next()); - String className = thisClass.name; - sb.append(indent + outerClassName + "::" + className + "& " + - outerClassName + "::get" + className + "()" + cr); - sb.append(indent + "{" + cr); - if (thisClass.versionSet.size() != globalVersionSet.size()) - { - sb.append(indent + tab + "if (!" + generateVersionCheck(thisClass.versionSet) + ")" + cr); - sb.append(indent + tab + tab + "throw new ProtocolVersionException();" + cr); - } - sb.append(indent + tab + "return " + - proxyInstanceName(thisClass, outerClassName) + ";" + cr); - sb.append(indent + "}" + cr); - if (cItr.hasNext()) - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassImpl(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - boolean firstClassFlag = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = thisClass.name; - if (!firstClassFlag) - sb.append(cr); - sb.append(indent + "// ==================== class " + className + - " ====================" + cr); - sb.append(generateInnerClassMethodImpls(thisClass, serverFlag, indentSize, tabSize)); - firstClassFlag = false; - } - return sb.toString(); - } - - protected String generateInnerClassMethodImpls(AmqpClass thisClass, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerclassName = proxyOuterClassName(serverFlag); - boolean first = true; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String methodBodyClassName = thisClass.name + Utils.firstUpper(method.name) + "Body"; - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - boolean versionConsistentFlag = method.isVersionConsistent(globalVersionSet); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - { - String methodName = parseForReservedWords(method.name, outerclassName + "." + thisClass.name); - AmqpOverloadedParameterMap overloadededParameterMap = - method.getOverloadedParameterLists(thisClass.versionSet, this); - for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) - { - AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); - if (!first) - sb.append(cr); - String returnType = "void"; - sb.append(indent + returnType + " " + outerclassName + "::" + thisClass.name + "::" + - methodName + "("); - sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5*tabSize), false, true, true)); - sb.append(")"); - if (versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + versionSet); - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(generateMethodBodyCallContext(method, thisFieldMap, outerclassName, methodBodyClassName, - versionConsistentFlag, versionSet, indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - protected String generateMethodBodyCallContext(AmqpMethod method, AmqpOrdinalFieldMap fieldMap, String outerclassName, - String methodBodyClassName, boolean versionConsistentFlag, AmqpVersionSet versionSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - if (versionConsistentFlag) - { - sb.append(generateProxyMethodBody(method, 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(generateProxyMethodBody(method, 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 generateProxyMethodBody(AmqpMethod method, AmqpOrdinalFieldMap fieldMap, String methodBodyClassName, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String namespace = version != null ? version.namespace() + "::" : ""; - StringBuffer sb = new StringBuffer(); - sb.append(indent+tab+"channel.send(make_shared_ptr(new "); - sb.append(namespace + methodBodyClassName + "( channel.getVersion()"); - sb.append(generateMethodParameterList(fieldMap, indentSize + (5*tabSize), true, false, true)); - sb.append(")));\n"); - 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 : model.classMap.keySet()) - { - thisClass = model.classMap.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.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "#include \"" + thisClass.name + - Utils.firstUpper(method.name) + "Body.h\"" + cr); - } - return sb.toString(); - } - - // Methods used for generation of code snippets for MethodBody class generation - - protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) - throws AmqpTemplateException - { - for (Integer thisIndex : indexMap.keySet()) - { - AmqpVersionSet versionSet = indexMap.get(thisIndex); - if (versionSet.contains(version)) - return String.valueOf(thisIndex); - } - throw new AmqpTemplateException("Unable to find index for version " + version); - } - - protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - if (version == null) - version = globalVersionSet.first(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); - for (Integer thisOrdinal : ordinalFieldMap.keySet()) - { - String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal); - sb.append(indent + fieldDomainPair[FIELD_CODE_TYPE] + " " + fieldDomainPair[FIELD_NAME] + ";" + cr); - } - return sb.toString(); - } - - protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - if (version == null) - version = globalVersionSet.first(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); - for (Integer thisOrdinal : ordinalFieldMap.keySet()) - { - String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal); - sb.append(indent + "" + setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " get" + - Utils.firstUpper(fieldDomainPair[FIELD_NAME]) + "() const { return " + - fieldDomainPair[FIELD_NAME] + "; }" + cr); - } - return sb.toString(); - } - - protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - if (version == null) - version = globalVersionSet.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) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList bitFieldList = new ArrayList(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); - Iterator oItr = ordinalFieldMap.keySet().iterator(); - int ordinal = 0; - while (oItr.hasNext()) - { - ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; - String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); - - // Defer bit types by adding them to an array. When the first subsequent non-bit - // type is encountered, then handle the bits. This allows consecutive bits to be - // placed into the same byte(s) - 8 bits to the byte. - if (domainType.compareTo("bit") == 0) - { - bitFieldList.add(fieldDomainPair[FIELD_NAME]); - } - else - { - if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) - { - sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); - } - sb.append(indent + "sz += " + - 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 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 + "sz += " + - typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + - "; /* " + comment + " */" + cr); - bitFieldList.clear(); - return sb.toString(); - } - - protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, - int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList bitFieldList = new ArrayList(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); - Iterator oItr = ordinalFieldMap.keySet().iterator(); - int ordinal = 0; - while (oItr.hasNext()) - { - ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; - String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); - - // Defer bit types by adding them to an array. When the first subsequent non-bit - // type is encountered, then handle the bits. This allows consecutive bits to be - // placed into the same byte(s) - 8 bits to the byte. - if (domainType.compareTo("bit") == 0) - { - bitFieldList.add(fieldDomainPair[FIELD_NAME]); - } - else - { - if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) - { - sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); - } - sb.append(indent + - typeMap.get(domainType).encodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + - "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */"+ cr); - } - } - if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types - { - sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); - } - - return sb.toString(); - } - - protected String generateBitEncodeMethodContents(ArrayList 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 = new ArrayList(); - AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, false, this); - Iterator oItr = ordinalFieldMap.keySet().iterator(); - int ordinal = 0; - while (oItr.hasNext()) - { - ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - AmqpVersion thisVersion = version == null ? globalVersionSet.first() : version; - String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); - - // Defer bit types by adding them to an array. When the first subsequent non-bit - // type is encountered, then handle the bits. This allows consecutive bits to be - // placed into the same byte(s) - 8 bits to the byte. - if (domainType.compareTo("bit") == 0) - { - bitFieldList.add(fieldDomainPair[FIELD_NAME]); - } - else - { - if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) - { - sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); - } - sb.append(indent + - typeMap.get(domainType).decodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + - "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + cr); - } - } - if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types - { - sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); - } - - return sb.toString(); - } - - protected String generateBitDecodeMethodContents(ArrayList 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 oItr = ordinalFieldMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - String[] fieldDomainPair = ordinalFieldMap.get(ordinal); - sb.append(indent + (defineFlag ? setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " " : "") + - fieldDomainPair[FIELD_NAME] + (initializerFlag ? "(" + fieldDomainPair[FIELD_NAME] + ")" : "") + - (oItr.hasNext() ? "," : "") + cr); - } - return sb.toString(); - } - - protected String generateMethodParameterList(AmqpOrdinalFieldMap fieldMap, int indentSize, - boolean leadingCommaFlag, boolean fieldTypeFlag, boolean fieldNameFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - Iterator pItr = fieldMap.keySet().iterator(); - while(pItr.hasNext()) - { - String[] field = fieldMap.get(pItr.next()); - if (first && leadingCommaFlag) - { - sb.append("," + (fieldNameFlag ? cr : " ")); - } - if (!first || leadingCommaFlag) - { - sb.append(indent); - } - sb.append( - (fieldTypeFlag ? setRef(field[FIELD_CODE_TYPE]) : "") + - (fieldNameFlag ? " " + field[FIELD_NAME] : "") + - (pItr.hasNext() ? "," + (fieldNameFlag ? cr : " ") : "")); - first = false; - } - return sb.toString(); - } - - protected String generateConstructor(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - if (method.fieldMap.size() > 0) - { - sb.append(indent + thisClass.name + Utils.firstUpper(method.name) + "Body(ProtocolVersion," + cr); - sb.append(generateFieldList(method.fieldMap, version, true, false, 8)); - sb.append(indent + tab + ")"); - if (method.fieldMap.size() > 0) { - sb.append(" : "); - sb.append(generateFieldList(method.fieldMap, version, false, true, 8)); - } - sb.append(indent + "{ }\n"); - } - return sb.toString(); - } - - protected String generateServerOperationsInvoke(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean special = isSpecialCase(thisClass.name, method.name); - - if (method.serverMethodFlagMap.size() > 0) // At least one AMQP version defines this method as a server method - { - Iterator bItr = method.serverMethodFlagMap.keySet().iterator(); - while (bItr.hasNext()) - { - if (bItr.next()) // This is a server operation - { - boolean fieldMapNotEmptyFlag = method.fieldMap.size() > 0; - sb.append(indent + "void invoke(AMQP_ServerOperations& target)\n"); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "target.get" + thisClass.name + "Handler()->" + - parseForReservedWords(Utils.firstLower(method.name), - thisClass.name + Utils.firstUpper(method.name) + "Body.invoke()") + "("); - if (special) - { - sb.append("*this"); - } - else if (fieldMapNotEmptyFlag) - { - sb.append(generateFieldList(method.fieldMap, version, false, false, indentSize + 4*tabSize)); - sb.append(indent + tab + tab + tab + tab); - } - sb.append(");" + cr); - sb.append(indent + "}" + cr); - } - } - } - return sb.toString(); - } - - protected String generateServerOperationsInvoke2(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - String ptrType = "AMQP_ServerOperations:: " + thisClass.name + "Handler*"; - if (isSpecialCase(thisClass.name, method.name)) { - sb.append(indent + "bool invoke(Invocable*)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "return false;" + cr); - sb.append(indent + "}" + cr); - } else if (method.serverMethodFlagMap.size() > 0) { // At least one AMQP version defines this method as a server method - - Iterator bItr = method.serverMethodFlagMap.keySet().iterator(); - while (bItr.hasNext()) - { - if (bItr.next()) // This is a server operation - { - boolean fieldMapNotEmptyFlag = method.fieldMap.size() > 0; - sb.append(indent + "bool invoke(Invocable* target)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + ptrType + " ptr = dynamic_cast<" + ptrType + ">(target);" + cr); - sb.append(indent + tab + "if (ptr) {" + cr); - sb.append(indent + tab + tab + "ptr->"); - sb.append(parseForReservedWords(Utils.firstLower(method.name),null) + "(" + cr); - if (fieldMapNotEmptyFlag) - { - sb.append(generateFieldList(method.fieldMap, version, false, false, indentSize + 4*tabSize)); - sb.append(indent + tab + tab + tab + tab); - } - sb.append(");" + cr); - sb.append(indent + tab + tab + "return true;" + cr); - sb.append(indent + tab + "} else {" + cr); - sb.append(indent + tab + tab + "return false;" + cr); - sb.append(indent + tab + "}" + 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.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "#include \"" + thisClass.name + Utils.firstUpper(method.name) + "Body.h\"" + cr); - } - } - - return sb.toString(); - } - - protected String generateMethodBodyInstances(AmqpModel model, int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "const " + thisClass.name + Utils.firstUpper(method.name) + "Body " + - Utils.firstLower(thisClass.name) + "_" + method.name + ";" + cr); - } - } - - return sb.toString(); - } - - protected String generateMethodBodyMapEntry(AmqpModel model, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - for (AmqpVersion version : globalVersionSet) - { - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String namespace = method.isVersionConsistent(globalVersionSet) ? "" : version.namespace() + "::"; - try - { - int classOrdinal = thisClass.indexMap.getOrdinal(version); - int methodOrdinal = method.indexMap.getOrdinal(version); - String methodModyClassName = namespace + thisClass.name + Utils.firstUpper(method.name) + "Body"; - 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) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - for (AmqpVersion v : versionSet) - { - if (!v.equals(versionSet.first())) - sb.append(" || "); - if (versionSet.size() > 1) - sb.append("("); - sb.append("version.equals(" + v.getMajor() + ", " + v.getMinor() + ")"); - if (versionSet.size() > 1) - sb.append(")"); - } - return sb.toString(); - } - - private String parseForReservedWords(String name, String context) - { - for (String cppReservedWord : cppReservedWords) - if (name.compareTo(cppReservedWord) == 0) - { - 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.equals("string") || - codeType.equals("FieldTable") || - codeType.equals("Content")) - return "const " + codeType + "&"; - return codeType; - } - - private String camelCaseName(String name, boolean upperFirstFlag) - { - StringBuffer ccn = new StringBuffer(); - String[] toks = name.split("[-_.\\ ]"); - for (int i=0; i0) - b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); - ccn.append(b); - } - return ccn.toString(); - } - - private boolean isSpecialCase(String className, String methodName) - { - return "message".equalsIgnoreCase(className) && ("transfer".equalsIgnoreCase(methodName) || "append".equalsIgnoreCase(methodName)); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java b/cpp/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java deleted file mode 100644 index 505a70dc85..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java +++ /dev/null @@ -1,339 +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.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.TreeMap; - -public class DotnetGenerator extends Generator -{ - private class DomainInfo - { - public String type; - public String size; - public String encodeExpression; - public String decodeExpression; - public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression) - { - this.type = domain; - this.size = size; - this.encodeExpression = encodeExpression; - this.decodeExpression = decodeExpression; - } - } - - private static TreeMap typeMap = new TreeMap(); - - public DotnetGenerator(AmqpVersionSet versionList) - { - super(versionList); - // Load .NET type and size maps. - // Adjust or add to these lists as new types are added/defined. - // The char '#' will be replaced by the field variable name (any type). - // The char '~' will be replaced by the compacted bit array size (type bit only). - // TODO: I have left a copy of the Java typeMap here - replace with appropriate .NET values. - typeMap.put("bit", new DomainInfo( - "boolean", // .NET code type - "~", // size - "EncodingUtils.writeBooleans(buffer, #)", // encode expression - "# = EncodingUtils.readBooleans(buffer)")); // decode expression - typeMap.put("content", new DomainInfo( - "Content", // .NET code type - "EncodingUtils.encodedContentLength(#)", // size - "EncodingUtils.writeContentBytes(buffer, #)", // encode expression - "# = EncodingUtils.readContent(buffer)")); // decode expression - typeMap.put("long", new DomainInfo( - "long", // .NET code type - "4", // size - "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression - "# = buffer.getUnsignedInt()")); // decode expression - typeMap.put("longlong", new DomainInfo( - "long", // .NET code type - "8", // size - "buffer.putLong(#)", // encode expression - "# = buffer.getLong()")); // decode expression - typeMap.put("longstr", new DomainInfo( - "byte[]", // .NET code type - "EncodingUtils.encodedLongstrLength(#)", // size - "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression - "# = EncodingUtils.readLongstr(buffer)")); // decode expression - typeMap.put("octet", new DomainInfo( - "short", // .NET code type - "1", // size - "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression - "# = buffer.getUnsigned()")); // decode expression - typeMap.put("short", new DomainInfo( - "int", // .NET code type - "2", // size - "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression - "# = buffer.getUnsignedShort()")); // decode expression - typeMap.put("shortstr", new DomainInfo( - "AMQShortString", // .NET code type - "EncodingUtils.encodedShortStringLength(#)", // size - "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression - "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression - typeMap.put("table", new DomainInfo( - "FieldTable", // .NET code type - "EncodingUtils.encodedFieldTableLength(#)", // size - "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression - "# = EncodingUtils.readFieldTable(buffer)")); // decode expression - typeMap.put("timestamp", new DomainInfo( - "long", // .NET code type - "8", // size - "EncodingUtils.writeTimestamp(buffer, #)", // encode expression - "# = EncodingUtils.readTimestamp(buffer)")); // decode expression - } - - @Override - protected String prepareFilename(String filenameTemplate, - AmqpClass thisClass, AmqpMethod method, AmqpField field) - { - StringBuffer sb = new StringBuffer(filenameTemplate); - if (thisClass != null) - replaceToken(sb, "${CLASS}", thisClass.name); - if (method != null) - replaceToken(sb, "${METHOD}", method.name); - if (field != null) - replaceToken(sb, "${FIELD}", field.name); - return sb.toString(); - } - - @Override - protected void processClassList(StringBuffer sb, int listMarkerStartIndex, - int listMarkerEndIndex, AmqpModel model) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // TODO: Add in tokens and calls to their corresponding generator methods here... - if (token.compareTo("${??????????}") == 0) - { - codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. -// 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) - throws AmqpTypeMappingException, AmqpTemplateException, - IllegalAccessException, InvocationTargetException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // TODO: Add in tokens and calls to their corresponding generator methods here... - if (token.compareTo("${??????????}") == 0) - { - codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. -// codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, -// mangledDeclarationGenerateMethod, 4, 4, this); - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, - int listMarkerEndIndex, AmqpClass thisClass) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // TODO: Add in tokens and calls to their corresponding generator methods here... - if (token.compareTo("${??????????}") == 0) - { - codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processTemplateA(String[] template) throws IOException, - AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, - AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) throws IOException, AmqpTemplateException, - AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - processTemplateD(template, thisClass, method, null); - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, - AmqpMethod method, AmqpField field) throws IOException, - AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - StringBuffer sb = new StringBuffer(template[1]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - try { processAllLists(sb, thisClass, method, null); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + template[templateFileNameIndex] + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, null); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + template[templateFileNameIndex] + ": " + e.getMessage()); - } - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - @Override - protected String processToken(String token, AmqpClass thisClass, - AmqpMethod method, AmqpField field, AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - // TODO Auto-generated method stub - return null; - } - - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - return globalDomainMap.getDomainType(domainName, version); - } - - public String getGeneratedType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - String domainType = globalDomainMap.getDomainType(domainName, version); - if (domainType == null) - { - 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; i0) - b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); - ccn.append(b); - } - return ccn.toString(); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/Generator.java b/cpp/gentools/src/org/apache/qpid/gentools/Generator.java deleted file mode 100644 index e7ccd64fbe..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/Generator.java +++ /dev/null @@ -1,429 +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.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.LineNumberReader; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; - -public abstract class Generator implements LanguageConverter -{ - protected static String cr = Utils.lineSeparator; - protected static enum EnumConstOutputTypes { OUTPUT_STRING, OUTPUT_INTEGER, OUTPUT_DOUBLE; }; - - // This string is reproduced in every generated file as a comment - // TODO: Tie the version info into the build system. - protected static final String generatorInfo = "Qpid Gentools v.0.1"; - protected static final int templateFileNameIndex = 0; - protected static final int templateStringIndex = 1; - - protected ArrayList modelTemplateList; - protected ArrayList classTemplateList; - protected ArrayList methodTemplateList; - protected ArrayList fieldTemplateList; - protected String genDir; - - protected AmqpVersionSet globalVersionSet; - protected AmqpDomainMap globalDomainMap; - protected AmqpConstantSet globalConstantSet; - protected AmqpModel model; - - protected int generatedFileCounter; - - public Generator(AmqpVersionSet versionList) - { - this.globalVersionSet = versionList; - modelTemplateList = new ArrayList(); - classTemplateList = new ArrayList(); - methodTemplateList = new ArrayList(); - fieldTemplateList = new ArrayList(); - generatedFileCounter = 0; - } - - public int getNumberGeneratedFiles() - { - return generatedFileCounter; - } - - public void setDomainMap(AmqpDomainMap domainMap) - { - this.globalDomainMap = domainMap; - } - - public AmqpDomainMap getDomainMap() - { - return globalDomainMap; - } - - public void setConstantSet(AmqpConstantSet constantSet) - { - this.globalConstantSet = constantSet; - } - - public AmqpConstantSet getConstantSet() - { - return globalConstantSet; - } - - public void setModel(AmqpModel model) - { - this.model = model; - } - - public AmqpModel getModel() - { - return model; - } - - public void initializeTemplates(File[] modelTemplateFiles, File[] classTemplatesFiles, - File[] methodTemplatesFiles, File[] fieldTemplatesFiles) - throws FileNotFoundException, IOException - { - if (modelTemplateFiles.length > 0) - { - System.out.println("Model template file(s):"); - for (File mtf : modelTemplateFiles) - { - System.out.println(" " + mtf.getAbsolutePath()); - String template[] = {mtf.getName(), loadTemplate(mtf)}; - modelTemplateList.add(template); - } - } - if (classTemplatesFiles.length > 0) - { - System.out.println("Class template file(s):"); - //for (int c=0; c 0) - { - System.out.println("Method template file(s):"); - for (File mtf : methodTemplatesFiles) - { - System.out.println(" " + mtf.getAbsolutePath()); - String template[] = {mtf.getName(), loadTemplate(mtf)}; - methodTemplateList.add(template); - } - } - if (fieldTemplatesFiles.length > 0) - { - System.out.println("Field template file(s):"); - for (File ftf : fieldTemplatesFiles) - { - System.out.println(" " + ftf.getAbsolutePath()); - String template[] = {ftf.getName(), loadTemplate(ftf)}; - fieldTemplateList.add(template); - } - } - } - - abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, - AmqpField field); - - abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, - AmqpField field, AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException; - - abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpModel model) - throws AmqpTemplateException, AmqpTypeMappingException; - - abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpClass thisClass) - throws AmqpTemplateException, AmqpTypeMappingException; - - abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap, AmqpVersion version) - throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, - InvocationTargetException; - - abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) - throws AmqpTemplateException, AmqpTypeMappingException; - - public void generate(File genDir) - throws TargetDirectoryException, IOException, AmqpTypeMappingException, - AmqpTemplateException, IllegalAccessException, InvocationTargetException - { - prepareTargetDirectory(genDir, true); - System.out.println("Generation directory: " + genDir.getAbsolutePath()); - this.genDir = genDir.getAbsolutePath(); - - // Use all model-level templates - for (String[] mt : modelTemplateList) - { - processTemplateA(mt); - } - - // Cycle through classes - for (String className : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(className); - // Use all class-level templates - for (String[] ct : classTemplateList) - { - processTemplateB(ct, thisClass); - } - - // Cycle through all methods - for (String methodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(methodName); - // Use all method-level templates - for (String[] mt : methodTemplateList) - { - processTemplateC(mt, thisClass, method); - } - - // Cycle through all fields - for (String fieldName : method.fieldMap.keySet()) - { - AmqpField field = method.fieldMap.get(fieldName); - // Use all field-level templates - for (String[] ft : fieldTemplateList) - { - processTemplateD(ft, thisClass, method, field); - } - } - } - } - } - - protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd) - throws AmqpTypeMappingException - { - int lend = sb.indexOf(Utils.lineSeparator, tokStart) + 1; // Include cr at end of line - String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr - sb.delete(tokStart, lend); - - for (AmqpVersion v : globalVersionSet) - { - // Insert copy of target line - StringBuffer isb = new StringBuffer(tline); - if (isb.indexOf("${protocol-version-list-entry}") >= 0) - { - String versionListEntry = " { ${major}, ${minor} }" + - (v.equals(globalVersionSet.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(); - } - } - - // Model-level template processing - abstract protected void processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Class-level template processing - abstract protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Method-level template processing - abstract protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Field-level template processing - abstract protected void processTemplateD(String[] template, AmqpClass thisClass, - AmqpMethod method, AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException; - - // Helper functions common to all generators - - protected static void prepareTargetDirectory(File dir, boolean createFlag) - throws TargetDirectoryException - { - if (dir.exists()) - { - if (!dir.isDirectory()) - throw new TargetDirectoryException("\"" + dir.getAbsolutePath() + - "\" exists, but is not a directory."); - } - else if (createFlag) // Create dir - { - if(!dir.mkdirs()) - throw new TargetDirectoryException("Unable to create directory \"" + - dir.getAbsolutePath() + "\"."); - } - else - throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() + - "\" not found."); - - } - - protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - int lstart = sb.indexOf("%{"); - while (lstart != -1) - { - int lend = sb.indexOf("}", lstart + 2); - if (lend > 0) - { - String listToken = sb.substring(lstart + 2, lend); - if (listToken.compareTo("VLIST") == 0) - { - processVersionList(sb, lstart, lend + 1); - } - else if (listToken.compareTo("CLIST") == 0) - { - processClassList(sb, lstart, lend + 1, model); - } - else if (listToken.compareTo("MLIST") == 0) - { - processMethodList(sb, lstart, lend + 1, thisClass); - } - else if (listToken.compareTo("FLIST") == 0) - { - // Pass the FieldMap from either a class or a method. - // If this is called from a class-level template, we assume that the - // class field list is required. In this case, method will be null. - processFieldList(sb, lstart, lend + 1, - (method == null ? thisClass.fieldMap : method.fieldMap), - version); - } - else if (listToken.compareTo("TLIST") == 0) - { - processConstantList(sb, lstart, lend + 1, globalConstantSet); - } - else - { - throw new AmqpTemplateException("Unknown list token \"%{" + listToken + - "}\" found in template at index " + lstart + "."); - } - } - lstart = sb.indexOf("%{", lstart + 1); - } - } - - protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - int lstart = sb.indexOf("${"); - while (lstart != -1) - { - int lend = sb.indexOf("}", lstart + 2); - if (lend > 0) - { - String token = sb.substring(lstart, lend + 1); - replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version)); - } - lstart = sb.indexOf("${", lstart); - } - } - - protected static void writeTargetFile(StringBuffer sb, File f) - throws IOException - { - FileWriter fw = new FileWriter(f); - fw.write(sb.toString().toCharArray()); - fw.flush(); - fw.close(); - } - - protected static String getTemplateFileName(StringBuffer sb) - throws AmqpTemplateException - { - if (sb.charAt(0) != '&') - throw new AmqpTemplateException("No filename marker &{filename} found at start of template."); - int cr = sb.indexOf(Utils.lineSeparator); - if (cr < 0) - throw new AmqpTemplateException("Bad template structure - unable to find first line."); - String fileName = sb.substring(2, cr-1); - sb.delete(0, cr + 1); - return fileName; - } - - protected static void replaceToken(StringBuffer sb, String token, String replacement) - { - replaceToken(sb, 0, token, replacement); - } - - protected static void replaceToken(StringBuffer sb, int index, String token, String replacement) - { - if (replacement != null) - { - int start = sb.indexOf(token, index); - int len = token.length(); - // Find first letter in token and determine if it is capitalized - char firstTokenLetter = getFirstLetter(token); - if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter)) - sb.replace(start, start+len, Utils.firstUpper(replacement)); - else - sb.replace(start, start+len, replacement); - } - } - - private static char getFirstLetter(String str) - { - int len = str.length(); - int index = 0; - char tokChar = str.charAt(index); - while (!Character.isLetter(tokChar) && index 0 && line.charAt(0) != '#') // Bad idea - '#' used in C/C++ files (#include)! - if (line.length() > 0) - sb.append(line + Utils.lineSeparator); - else - sb.append(Utils.lineSeparator); - line = lnr.readLine(); - } - lnr.close(); - fr.close(); - return sb.toString(); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/cpp/gentools/src/org/apache/qpid/gentools/JavaGenerator.java deleted file mode 100644 index 9acfaf65fa..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/JavaGenerator.java +++ /dev/null @@ -1,1702 +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.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.TreeMap; - -public class JavaGenerator extends Generator -{ - // TODO: Move this to parent class - protected static final int FIELD_NAME = 0; - protected static final int FIELD_CODE_TYPE = 1; - - private class DomainInfo - { - public String type; - public String size; - public String encodeExpression; - public String decodeExpression; - public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression) - { - this.type = domain; - this.size = size; - this.encodeExpression = encodeExpression; - this.decodeExpression = decodeExpression; - } - } - - private static TreeMap typeMap = new TreeMap(); - - // Methods used for generation of code snippets called from the field map parsers - - // Common methods - static private Method declarationGenerateMethod; - static private Method mangledDeclarationGenerateMethod; - - // Methods for MessageBody classes - static private Method mbGetGenerateMethod; - static private Method mbMangledGetGenerateMethod; - static private Method mbParamListGenerateMethod; - static private Method mbPassedParamListGenerateMethod; - static private Method mbMangledParamListGenerateMethod; - static private Method mbMangledPassedParamListGenerateMethod; - static private Method mbBodyInitGenerateMethod; - static private Method mbMangledBodyInitGenerateMethod; - static private Method mbSizeGenerateMethod; - static private Method mbBitSizeGenerateMethod; - static private Method mbEncodeGenerateMethod; - static private Method mbBitEncodeGenerateMethod; - static private Method mbDecodeGenerateMethod; - static private Method mbBitDecodeGenerateMethod; - static private Method mbToStringGenerateMethod; - static private Method mbBitToStringGenerateMethod; - - // Methods for PropertyContentHeader classes - static private Method pchClearGenerateMethod; - static private Method pchMangledClearGenerateMethod; - static private Method pchGetGenerateMethod; - static private Method pchMangledGetGenerateMethod; - static private Method pchSetGenerateMethod; - static private Method pchMangledSetGenerateMethod; - static private Method pchSizeGenerateMethod; - static private Method pchBitSizeGenerateMethod; - static private Method pchEncodeGenerateMethod; - static private Method pchBitEncodeGenerateMethod; - static private Method pchDecodeGenerateMethod; - static private Method pchBitDecodeGenerateMethod; - static private Method pchGetPropertyFlagsGenerateMethod; - static private Method pchBitGetPropertyFlagsGenerateMethod; - static private Method pchSetPropertyFlagsGenerateMethod; - static private Method pchBitSetPropertyFlagsGenerateMethod; - - static - { - // ************** - // Common methods - // ************** - - // Methods for AmqpFieldMap.parseFieldMap() - - try { declarationGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateFieldDeclaration", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mangledDeclarationGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMangledFieldDeclaration", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - - // ******************************* - // Methods for MessageBody classes - // ******************************* - - // Methods for AmqpFieldMap.parseFieldMap() - - try { mbGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbGetMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledGetMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbParamList", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - - try { mbPassedParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbPassedParamList", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledParamList", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledPassedParamListGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledPassedParamList", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBodyInitGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBodyInit", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbMangledBodyInitGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbMangledBodyInit", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - // Methods for AmqpFieldMap.parseFieldMapOrdinally() - - try { mbSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldSize", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitArrayFieldSize", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldEncode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitFieldEncode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldDecode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitFieldDecode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbToStringGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbFieldToString", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { mbBitToStringGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generateMbBitFieldToString", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - // ***************************************** - // Methods for PropertyContentHeader classes - // ***************************************** - - // Methods for AmqpFieldMap.parseFieldMap() - - try { pchClearGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchClearMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchMangledClearGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchMangledClearMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchSetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchSetMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchMangledSetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchMangledSetMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchGetMethod", String.class, AmqpField.class, - AmqpVersionSet.class, int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchMangledGetGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchMangledGetMethod", AmqpField.class, - int.class, int.class, boolean.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - // Methods for AmqpFieldMap.parseFieldMapOrdinally() - - try { pchSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchFieldSize", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitSizeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitArrayFieldSize", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchFieldEncode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitEncodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitFieldEncode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchFieldDecode", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitDecodeGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitFieldDecode", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchGetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchGetPropertyFlags", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitGetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitGetPropertyFlags", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchSetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchSetPropertyFlags", String.class, String.class, - int.class, int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - - try { pchBitSetPropertyFlagsGenerateMethod = JavaGenerator.class.getDeclaredMethod( - "generatePchBitSetPropertyFlags", ArrayList.class, int.class, - int.class, int.class); } - catch (NoSuchMethodException e) { e.printStackTrace(); } - } - - public JavaGenerator(AmqpVersionSet versionList) - { - super(versionList); - // Load Java type and size maps. - // Adjust or add to these lists as new types are added/defined. - // The char '#' will be replaced by the field variable name (any type). - // The char '~' will be replaced by the compacted bit array size (type bit only). - typeMap.put("bit", new DomainInfo( - "boolean", // Java code type - "~", // size - "EncodingUtils.writeBooleans(buffer, #)", // encode expression - "# = EncodingUtils.readBooleans(buffer)")); // decode expression - typeMap.put("content", new DomainInfo( - "Content", // Java code type - "EncodingUtils.encodedContentLength(#)", // size - "EncodingUtils.writeContentBytes(buffer, #)", // encode expression - "# = EncodingUtils.readContent(buffer)")); // decode expression - typeMap.put("long", new DomainInfo( - "long", // Java code type - "4", // size - "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression - "# = buffer.getUnsignedInt()")); // decode expression - typeMap.put("longlong", new DomainInfo( - "long", // Java code type - "8", // size - "buffer.putLong(#)", // encode expression - "# = buffer.getLong()")); // decode expression - typeMap.put("longstr", new DomainInfo( - "byte[]", // Java code type - "EncodingUtils.encodedLongstrLength(#)", // size - "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression - "# = EncodingUtils.readLongstr(buffer)")); // decode expression - typeMap.put("octet", new DomainInfo( - "short", // Java code type - "1", // size - "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression - "# = buffer.getUnsigned()")); // decode expression - typeMap.put("short", new DomainInfo( - "int", // Java code type - "2", // size - "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression - "# = buffer.getUnsignedShort()")); // decode expression - typeMap.put("shortstr", new DomainInfo( - "AMQShortString", // Java code type - "EncodingUtils.encodedShortStringLength(#)", // size - "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression - "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression - typeMap.put("table", new DomainInfo( - "FieldTable", // Java code type - "EncodingUtils.encodedFieldTableLength(#)", // size - "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression - "# = EncodingUtils.readFieldTable(buffer)")); // decode expression - typeMap.put("timestamp", new DomainInfo( - "long", // Java code type - "8", // size - "EncodingUtils.writeTimestamp(buffer, #)", // encode expression - "# = EncodingUtils.readTimestamp(buffer)")); // decode expression - } - - // === Start of methods for Interface LanguageConverter === - - public String prepareClassName(String className) - { - return camelCaseName(className, true); - } - - public String prepareMethodName(String methodName) - { - return camelCaseName(methodName, false); - } - - public String prepareDomainName(String domainName) - { - return camelCaseName(domainName, false); - } - - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - return globalDomainMap.getDomainType(domainName, version); - } - - public String getGeneratedType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - String domainType = globalDomainMap.getDomainType(domainName, version); - if (domainType == null) - { - throw new AmqpTypeMappingException("Domain type \"" + domainName + - "\" not found in Java typemap."); - } - DomainInfo info = typeMap.get(domainType); - if (info == null) - { - throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); - } - return info.type; - } - - - // === Abstract methods from class Generator - Java-specific implementations === - - @Override - protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, - AmqpField field) - { - StringBuffer sb = new StringBuffer(filenameTemplate); - if (thisClass != null) - replaceToken(sb, "${CLASS}", thisClass.name); - if (method != null) - replaceToken(sb, "${METHOD}", method.name); - if (field != null) - replaceToken(sb, "${FIELD}", field.name); - return sb.toString(); - } - - @Override - protected void processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, method, null); - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, - AmqpMethod method, AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[1]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, - AmqpField field, String templateFileName, AmqpVersion version) - throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException - { - try { processAllLists(sb, thisClass, method, version); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, version); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); - } - } - - @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - if (token.compareTo("${GENERATOR}") == 0) - return generatorInfo; - if (token.compareTo("${CLASS}") == 0 && thisClass != null) - return thisClass.name; - if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) - return generateIndexInitializer("registerClassId", thisClass.indexMap, 8); - if (token.compareTo("${METHOD}") == 0 && method != null) - return method.name; - if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) - return generateIndexInitializer("registerMethodId", method.indexMap, 8); - if (token.compareTo("${FIELD}") == 0 && field != null) - return field.name; - - // This token is used only with class or method-level templates - if (token.compareTo("${pch_property_flags_declare}") == 0) - { - return generatePchPropertyFlagsDeclare(); - } - else if (token.compareTo("${pch_property_flags_initializer}") == 0) - { - int mapSize = method == null ? thisClass.fieldMap.size() : method.fieldMap.size(); - return generatePchPropertyFlagsInitializer(mapSize); - } - else if (token.compareTo("${pch_compact_property_flags_initializer}") == 0) - { - return generatePchCompactPropertyFlagsInitializer(thisClass, 8, 4); - } - else if (token.compareTo("${pch_compact_property_flags_check}") == 0) - { - return generatePchCompactPropertyFlagsCheck(thisClass, 8, 4); - } - - // Oops! - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - @Override - protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpModel model) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - if (token.compareTo("${reg_map_put_method}") == 0) - { - codeSnippet = generateRegistry(model, 8, 4); - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpClass thisClass) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - //TODO - we don't have any cases of this (yet). - if (token.compareTo("${???}") == 0) - { - codeSnippet = token; - } - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap, AmqpVersion version) - throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, - InvocationTargetException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // Field declarations - common to MethodBody and PropertyContentHeader classes - if (token.compareTo("${field_declaration}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, - mangledDeclarationGenerateMethod, 4, 4, this); - } - - // MethodBody classes - else if (token.compareTo("${mb_field_get_method}") == 0) - { - codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod, - mbMangledGetGenerateMethod, 4, 4, this); - } - else if (token.compareTo("${mb_field_parameter_list}") == 0) - { - // 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 : ""; - // - codeSnippet += fieldMap.parseFieldMap(mbParamListGenerateMethod, - mbMangledParamListGenerateMethod, 42, 4, this); - } - - else if (token.compareTo("${mb_field_passed_parameter_list}") == 0) - { - // 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 : ""; - // - 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) - throws AmqpTemplateException, AmqpTypeMappingException - - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - if (token.compareTo("${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.name + - "; // AMQP version(s): " + versionSet + cr; - } - - protected String generateMangledFieldDeclaration(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(Utils.createSpaces(indentSize) + "public " + codeType + " " + - field.name + "_" + (domainCntr++) + "; // AMQP Version(s): " + versionSet + - cr); - } - return sb.toString(); - } - - protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - - for (Integer index : indexMap.keySet()) - { - AmqpVersionSet versionSet = indexMap.get(index); - for (AmqpVersion version : versionSet) - { - sb.append(indent + mapName + "( (byte) " + version.getMajor() +", (byte) " + version.getMinor() + ", " + index + ");" + cr); - } - } - return sb.toString(); - } - - protected String generateRegistry(AmqpModel model, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - - for (String className : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(className); - for (String methodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(methodName); - for (AmqpVersion version : globalVersionSet) - { - // Find class and method index for this version (if it exists) - try - { - int classIndex = findIndex(thisClass.indexMap, version); - int methodIndex = findIndex(method.indexMap, version); - sb.append(indent + "registerMethod(" + cr); - sb.append(indent + tab + "(short)" + classIndex + - ", (short)" + methodIndex + ", (byte)" + version.getMajor() + - ", (byte)" + version.getMinor() + ", " + cr); - sb.append(indent + tab + Utils.firstUpper(thisClass.name) + - Utils.firstUpper(method.name) + "Body.getFactory());" + cr); - } - catch (Exception e) {} // Ignore - } - } - } - return sb.toString(); - } - - protected int findIndex(TreeMap map, AmqpVersion version) - throws Exception - { - Iterator iItr = map.keySet().iterator(); - while (iItr.hasNext()) - { - int index = iItr.next(); - AmqpVersionSet versionSet = map.get(index); - if (versionSet.contains(version)) - return index; - } - throw new Exception("Index not found"); - } - - // Methods for AmqpConstants class - - protected String generateConstantGetMethods(AmqpConstantSet constantSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - Iterator cItr = constantSet.iterator(); - while (cItr.hasNext()) - { - AmqpConstant constant = cItr.next(); - if (constant.isVersionConsistent(globalVersionSet)) - { - // return a constant - String value = constant.firstKey(); - sb.append(indent + "public static String " + constant.name + "() { return \"" + - constant.firstKey() + "\"; }" + cr); - if (Utils.containsOnlyDigits(value)) - { - sb.append(indent + "public static int " + constant.name + "AsInt() { return " + - constant.firstKey() + "; }" + cr); - } - if (Utils.containsOnlyDigitsAndDecimal(value)) - { - sb.append(indent + "public static double " + constant.name + "AsDouble() { return (double)" + - 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) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "public static " + methodReturnType + " " + constant.name + - methodNameSuffix + "(byte major, byte minor) throws AMQProtocolVersionException" + cr); - sb.append(indent + "{" + cr); - boolean first = true; - Iterator 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.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); - } - else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(value)) - { - sb.append(generateConstantDeclarationException(constant.name, 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.name + "\\\" \" +" + 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.name) + "() { return " + field.name + "; }" + - cr; - } - - protected String generateMbMangledGetMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(cr); - sb.append(indent + "public T get" + Utils.firstUpper(field.name) + - "(Class classObj) throws AMQProtocolVersionException" + cr); - sb.append(indent + "{" + cr); - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(indent + tab + "if (classObj.equals(" + codeType + - ".class)) // AMQP Version(s): " + versionSet + cr); - sb.append(indent + tab + tab + "return (T)(Object)" + field.name + "_" + - (domainCntr++) + ";" + cr); - } - sb.append(indent + tab + - "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + - cr + " \"field \\\"" + field.name + - "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generateMbParamList(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + codeType + " " + field.name + - (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + cr; - } - - - protected String generateMbPassedParamList(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + field.name + - (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + cr; - } - - - protected String generateMbMangledParamList(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(Utils.createSpaces(indentSize) + codeType + " " + field.name + "_" + - (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + - versionSet + cr); - } - return sb.toString(); - } - - protected String generateMbMangledPassedParamList(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - sb.append(Utils.createSpaces(indentSize) + field.name + "_" + - (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + - versionSet + cr); - } - return sb.toString(); - } - - - protected String generateMbBodyInit(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - { - return Utils.createSpaces(indentSize) + "this." + field.name + " = " + field.name + - ";" + cr; - } - - protected String generateMbMangledBodyInit(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - dItr.next(); - sb.append(Utils.createSpaces(indentSize) + "bodyFrame." + field.name + "_" + domainCntr + - " = " + field.name + "_" + (domainCntr++) + ";" + cr); - } - return sb.toString(); - } - - protected String generateMbFieldSize(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldName) + - "; // " + fieldName + ": " + domainType + cr); - return sb.toString(); - } - - protected String generateMbBitArrayFieldSize(ArrayList bitFieldList, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - int numBytes = ((bitFieldList.size() - 1) / 8) + 1; - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - sb.append(Utils.createSpaces(indentSize) + "size += " + - typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + - "; // " + comment + cr); - return sb.toString(); - } - - protected String generateMbFieldEncode(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) + - "; // " + fieldName + ": " + domain + cr); - return sb.toString(); - } - - protected String generateMbBitFieldEncode(ArrayList bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - - StringBuilder sb = new StringBuilder(); - int i = 0; - while(i bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - - StringBuilder sb = new StringBuilder(indent); - // Multiple occurrences of byte value blocks will result in multiple declarations - // unless each is named uniquely. - String varName = "packedValue_" + ordinal; - sb.append("byte " + varName + ";"); - sb.append(cr); - - // RG HERE! - - int i = 0; - while(i < bitFieldList.size()) - { - sb.append(indent + varName + " = EncodingUtils.readByte(buffer);" + cr); - - for(int j = 0; i < bitFieldList.size() && j < 8; i++, j++) - { - sb.append(indent + bitFieldList.get(i) + " = ( " + varName + " & (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(); - if (domain.compareTo("longstr") == 0) - { - sb.append(Utils.createSpaces(indentSize) + - "buf.append(\" " + fieldName + ": \" + (" + fieldName + - " == null ? \"\" : new String(" + fieldName + ")));" + cr); - } - else - { - sb.append(Utils.createSpaces(indentSize) + - "buf.append(\" " + fieldName + ": \" + " + fieldName + ");" + cr); - } - return sb.toString(); - } - - protected String generateMbBitFieldToString(ArrayList bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - for (int i=0; i oItr = field.ordinalMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - AmqpVersionSet versionSet = field.ordinalMap.get(ordinal); - sb.append(indent + tab); - if (ordinal != field.ordinalMap.firstKey()) - sb.append("else "); - sb.append("if ("); - sb.append(generateVersionCheck(versionSet)); - sb.append(")" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = false;" + cr); - sb.append(indent + tab + "}" + cr); - } - } - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchGetMethod(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(indent + "public " + codeType + " get" + - Utils.firstUpper(field.name) + "()" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "decodeIfNecessary();" + cr); - sb.append(indent + tab + "return " + field.name + ";" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchMangledGetMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(indent + "public T get" + - Utils.firstUpper(field.name) + - "(Class classObj) throws AMQProtocolVersionException" + cr); - sb.append(indent + "{" + cr); - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - sb.append(indent + tab + "if (classObj.equals(" + codeType + - ".class)) // AMQP Version(s): " + versionSet + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "decodeIfNecessary();" + cr); - sb.append(indent + tab + tab + "return (T)(Object)" + field.name + "_" + - (domainCntr++) + ";" + cr); - sb.append(indent + tab + "}" + cr); - } - sb.append(indent + tab + - "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + - cr + " \"field \\\"" + field.name + - "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchSetMethod(String codeType, AmqpField field, - AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "public void set" + Utils.firstUpper(field.name) + - "(" + codeType + " " + field.name + ")" + cr); - sb.append(indent + "{" + cr); - - // If there is more than one ordinal for this field or the ordinal does not - // apply to all known versions, then we need to generate version checks so - // we know which fieldProperty to clear. - if (field.ordinalMap.size() == 1 && - field.ordinalMap.get(field.ordinalMap.firstKey()).size() == globalVersionSet.size()) - { - int ordinal = field.ordinalMap.firstKey(); - sb.append(indent + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + "propertyFlags[" + ordinal + "] = true;" + cr); - sb.append(indent + tab + "this." + field.name + " = " + field.name + ";" + cr); - } - else - { - Iterator oItr = field.ordinalMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - AmqpVersionSet oVersionSet = field.ordinalMap.get(ordinal); - sb.append(indent + tab); - if (ordinal != field.ordinalMap.firstKey()) - sb.append("else "); - sb.append("if ("); - sb.append(generateVersionCheck(oVersionSet)); - sb.append(")" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + cr); - sb.append(indent + tab + tab + "this." + field.name + " = " + field.name + ";" + cr); - sb.append(indent + tab + "}" + cr); - } - } - sb.append(indent + "}" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchMangledSetMethod(AmqpField field, int indentSize, - int tabSize, boolean nextFlag) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - - Iterator dItr = field.domainMap.keySet().iterator(); - int domainCntr = 0; - while (dItr.hasNext()) - { - String domainName = dItr.next(); - AmqpVersionSet versionSet = field.domainMap.get(domainName); - String codeType = getGeneratedType(domainName, versionSet.first()); - - // Find ordinal with matching version - AmqpVersionSet commonVersionSet = new AmqpVersionSet(); - Iterator oItr = field.ordinalMap.keySet().iterator(); - while (oItr.hasNext()) - { - int ordinal = oItr.next(); - AmqpVersionSet oVersionSet = field.ordinalMap.get(ordinal); - Iterator vItr = oVersionSet.iterator(); - boolean first = true; - while (vItr.hasNext()) - { - AmqpVersion thisVersion = vItr.next(); - if (versionSet.contains(thisVersion)) - commonVersionSet.add(thisVersion); - } - if (!commonVersionSet.isEmpty()) - { - sb.append(indent + "public void set" + Utils.firstUpper(field.name) + - "(" + codeType + " " + field.name + ")" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab); - if (!first) - sb.append("else "); - sb.append("if ("); - sb.append(generateVersionCheck(commonVersionSet)); - sb.append(")" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "clearEncodedForm();" + cr); - sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + cr); - sb.append(indent + tab + tab + "this." + field.name + "_" + (domainCntr++) + - " = " + field.name + ";" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + "}" + cr); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - protected String generatePchFieldSize(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(indent + "if (propertyFlags[" + ordinal + "]) // " + - fieldName + ": " + domainType + cr); - sb.append(indent + Utils.createSpaces(tabSize) + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldName) + ";" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchBitArrayFieldSize(ArrayList bitFieldList, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - StringBuffer sb = new StringBuffer(); - - if (bitFieldList.size() == 1) // single bit - { - sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + comment + cr); - sb.append(indent + tab + "size += " + - typeMap.get("bit").size.replaceAll("~", "1") + ";" + cr); - } - else // multiple bits - up to 8 are combined into one byte - { - String bitCntrName = "bitCntr_" + ordinal; - int startOrdinal = ordinal - bitFieldList.size(); - sb.append(indent + "// " + comment + cr); - sb.append(indent + "int " + bitCntrName + " = 0;" + cr); - sb.append(indent + "for (int i=" + startOrdinal + "; i<" + ordinal + "; i++)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "if (propertyFlags[i])" + cr); - sb.append(indent + tab + tab + bitCntrName + "++;" + cr); - sb.append(indent + "}" + cr); - sb.append(indent + "size += " + - typeMap.get("bit").size.replaceAll("~", bitCntrName + - " > 0 ? ((" + bitCntrName + " - 1) / 8) + 1 : 0") + ";" + cr); - } - sb.append(cr); - return sb.toString(); - } - - protected String generatePchFieldEncode(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + - domainType + cr); - sb.append(indent + Utils.createSpaces(tabSize) + - typeMap.get(domainType).encodeExpression.replaceAll("#", fieldName) + ";" + cr); - sb.append(cr); - return sb.toString(); - } - - protected String generatePchBitFieldEncode(ArrayList 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, - 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, - 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 0;" + cr); - return sb.toString(); - } - - protected String generatePchBitSetPropertyFlags(ArrayList 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 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 vItr = globalVersionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - int numBytes = ((thisClass.fieldMap.getNumFields(version) - 1) / 15) + 1; - - sb.append(indent); - if (!version.equals(globalVersionSet.first())) - sb.append("else "); - sb.append("if ( major == " + version.getMajor() + " && minor == " + - version.getMinor() + " )" + cr); - sb.append(indent + tab + "compactPropertyFlags = new int[] { "); - for (int i=0; i vItr = globalVersionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - int numFields = thisClass.fieldMap.getNumFields(version); - int numBytes = ((numFields - 1) / 15) + 1; - - sb.append(indent); - if (!version.equals(globalVersionSet.first())) - sb.append("else "); - sb.append("if ( major == " + version.getMajor() + " && minor == " + - version.getMinor() + " && compactPropertyFlags.length != " + numBytes + " )" + cr); - sb.append(indent + tab + - "throw new AMQProtocolVersionException(\"Property flag array size mismatch:\" +" + cr); - sb.append(indent + tab + tab + "\"(Size found: \" + compactPropertyFlags.length +" + cr); - sb.append(indent + tab + tab + "\") Version " + version + " has " + numFields + - " fields which requires an int array of size " + numBytes + ".\");" + cr); - } - return sb.toString(); - } - - private String generateVersionCheck(AmqpVersionSet v) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - AmqpVersion[] versionArray = new AmqpVersion[v.size()]; - v.toArray(versionArray); - for (int i=0; i 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; i0) - b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); - ccn.append(b); - } - return ccn.toString(); - } -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/LanguageConverter.java b/cpp/gentools/src/org/apache/qpid/gentools/LanguageConverter.java deleted file mode 100644 index cb0a14e3bc..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/LanguageConverter.java +++ /dev/null @@ -1,39 +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 void setDomainMap(AmqpDomainMap domainMap); - public AmqpDomainMap getDomainMap(); - - public void setConstantSet(AmqpConstantSet constantSet); - public AmqpConstantSet getConstantSet(); - - public void setModel(AmqpModel model); - public AmqpModel getModel(); - - public String prepareClassName(String className); - public String prepareMethodName(String methodName); - public String prepareDomainName(String domainName); - public String getDomainType(String domainName, AmqpVersion version) throws AmqpTypeMappingException; - public String getGeneratedType(String domainName, AmqpVersion version) throws AmqpTypeMappingException; -} diff --git a/cpp/gentools/src/org/apache/qpid/gentools/Main.java b/cpp/gentools/src/org/apache/qpid/gentools/Main.java deleted file mode 100644 index a25ddd103c..0000000000 --- a/cpp/gentools/src/org/apache/qpid/gentools/Main.java +++ /dev/null @@ -1,347 +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.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - -public class Main -{ - private static final String defaultOutDir = ".." + Utils.fileSeparator + "gen"; - private static final String defaultCppTemplateDir = ".." + Utils.fileSeparator + "templ.cpp"; - private static final String defaultDotnetTemplateDir = ".." + Utils.fileSeparator + "templ.net"; - private static final String defaultJavaTemplateDir = ".." + Utils.fileSeparator + "templ.java"; - - private enum GeneratorLangEnum { CPP, DOTNET, JAVA } - - private DocumentBuilder docBuilder; - private AmqpVersionSet versionSet; - private Generator generator; - private AmqpConstantSet constants; - private AmqpDomainMap domainMap; - private AmqpModel model; - - private String outDir; - private String tmplDir; - private GeneratorLangEnum generatorLang; - private ArrayList xmlFiles; - private File[] modelTemplateFiles; - private File[] classTemplateFiles; - private File[] methodTemplateFiles; - private File[] fieldTemplateFiles; - - public Main() throws ParserConfigurationException - { - docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - versionSet = new AmqpVersionSet(); - xmlFiles = new ArrayList(); - } - - public void run(String[] args) - throws IOException, - SAXException, - AmqpParseException, - AmqpTypeMappingException, - AmqpTemplateException, - TargetDirectoryException, - IllegalAccessException, - InvocationTargetException - { - modelTemplateFiles = new File[]{}; - classTemplateFiles = new File[]{}; - methodTemplateFiles = new File[]{}; - fieldTemplateFiles = new File[]{}; - - // 0. Initialize - outDir = defaultOutDir; - tmplDir = null; - generatorLang = GeneratorLangEnum.CPP; // Default generation language - xmlFiles.clear(); - processArgs(args); - switch (generatorLang) - { - case JAVA: - prepareJava(); - break; - case DOTNET: - prepareDotnet(); - break; - default: - prepareCpp(); - } - - if (modelTemplateFiles.length == 0 && classTemplateFiles.length == 0 && - methodTemplateFiles.length == 0 && fieldTemplateFiles.length == 0) - System.err.println(" WARNING: No template files."); - - // 1. Suck in all the XML spec files provided on the command line - analyzeXML(); - - // 2. Load up all templates - try - { - generator.initializeTemplates(modelTemplateFiles, classTemplateFiles, - methodTemplateFiles, fieldTemplateFiles); - } - catch (FileNotFoundException e) - { - System.err.println("Error: Unable to load template file (check -t option on command-line):"); - System.err.println(e.getMessage()); - return; - } - - // 3. Generate output - generator.generate(new File(outDir)); - - System.out.println("Files generated: " + generator.getNumberGeneratedFiles()); - System.out.println("Done."); - } - - private void processArgs(String[] args) - { - // Crude but simple... - for (int i=0; i - -#include "qpid/framing/ProtocolVersion.h" - -namespace qpid { -namespace framing { - -class AMQMethodBody; - -class AMQP_ClientOperations -{ -public: - virtual ~AMQP_ClientOperations() {} - - virtual ProtocolVersion getVersion() const = 0; - - // 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/cpp/gentools/templ.cpp/AMQP_Constants.h.tmpl b/cpp/gentools/templ.cpp/AMQP_Constants.h.tmpl deleted file mode 100644 index 4631bc8de6..0000000000 --- a/cpp/gentools/templ.cpp/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 included. - - // Constant getValue methods - -%{TLIST} ${ch_get_value_method} - \ No newline at end of file diff --git a/cpp/gentools/templ.cpp/AMQP_HighestVersion.h.tmpl b/cpp/gentools/templ.cpp/AMQP_HighestVersion.h.tmpl deleted file mode 100644 index a3932d7cb5..0000000000 --- a/cpp/gentools/templ.cpp/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 "qpid/framing/ProtocolVersion.h" - - -namespace qpid { -namespace framing { - -static ProtocolVersion highestProtocolVersion(${hv_latest_major}, ${hv_latest_minor}); - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/cpp/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl b/cpp/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl deleted file mode 100644 index ee89386653..0000000000 --- a/cpp/gentools/templ.cpp/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 -#include "qpid/framing/ProtocolVersionException.h" -#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/cpp/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl b/cpp/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl deleted file mode 100644 index 09611c8d31..0000000000 --- a/cpp/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl +++ /dev/null @@ -1,72 +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 "qpid/framing/ProtocolVersion.h" - -namespace qpid { -namespace framing { - -class AMQMethodBody; - -class Invocable -{ -protected: - Invocable() {} - virtual ~Invocable() {} -}; - -class AMQP_ServerOperations -{ -protected: - ProtocolVersion version; - -public: - virtual ~AMQP_ServerOperations() {} - - virtual ProtocolVersion getVersion() const = 0; - - // 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/cpp/gentools/templ.cpp/MethodBodyClass.h.tmpl b/cpp/gentools/templ.cpp/MethodBodyClass.h.tmpl deleted file mode 100644 index 5ffd2f2b4d..0000000000 --- a/cpp/gentools/templ.cpp/MethodBodyClass.h.tmpl +++ /dev/null @@ -1,115 +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 -#include - -#include "qpid/framing/amqp_types.h" -#include "qpid/framing/${mb_base_class}.h" -#include "qpid/framing/Buffer.h" -#include "qpid/framing/FieldTable.h" -#include "qpid/framing/FramingContent.h" -#include "qpid/framing/SequenceNumberSet.h" -#include "qpid/framing/AMQP_ServerOperations.h" -#include "qpid/framing/MethodBodyConstVisitor.h" - - -namespace qpid -{ -namespace framing -{ -${version_namespace_start} - -class ${CLASS}${METHOD}Body : public AMQMethodBody -{ - - // Method field declarations - -%{FLIST} ${mb_field_declaration} - - -public: - static const ClassId CLASS_ID= ${CLASS_ID_INIT}; - static const MethodId METHOD_ID = ${METHOD_ID_INIT}; - - // Constructors and destructors - -${mb_constructor_with_initializers} - - ${CLASS}${METHOD}Body(ProtocolVersion=ProtocolVersion()) {} - virtual ~${CLASS}${METHOD}Body() {} - - // Attribute get methods - -%{FLIST} ${mb_field_get_method} - - // Helper methods - using AMQMethodBody::accept; - void accept(MethodBodyConstVisitor& v) const { v.visit(*this); } - - void print(std::ostream& out) const - { - out << "${CLASS}${METHOD}: "; -%{FLIST} ${mb_field_print} - } - - inline ClassId amqpClassId() const { return CLASS_ID; } - inline MethodId amqpMethodId() const { return METHOD_ID; } - - u_int32_t size() const - { - u_int32_t sz = 0; -%{FLIST} ${mb_body_size} - return sz; - } - - void encode(Buffer& ${mb_buffer_param}) const - { -%{FLIST} ${mb_encode} - } - - inline void decode(Buffer& ${mb_buffer_param}, uint32_t=0) - { -%{FLIST} ${mb_decode} - } - -${mb_server_operation_invoke} - -${mb_server_operation_invoke2} - -}; // class ${CLASS}${METHOD}Body - -${version_namespace_end} -} // namespace framing -} // namespace qpid - -#endif - diff --git a/cpp/gentools/templ.java/AmqpConstantsClass.tmpl b/cpp/gentools/templ.java/AmqpConstantsClass.tmpl deleted file mode 100644 index 8d459f2977..0000000000 --- a/cpp/gentools/templ.java/AmqpConstantsClass.tmpl +++ /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/cpp/gentools/templ.java/MethodBodyClass.tmpl b/cpp/gentools/templ.java/MethodBodyClass.tmpl deleted file mode 100644 index 42582fcb7c..0000000000 --- a/cpp/gentools/templ.java/MethodBodyClass.tmpl +++ /dev/null @@ -1,180 +0,0 @@ -&{${CLASS}${METHOD}Body.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 java.util.HashMap; - -import org.apache.mina.common.ByteBuffer; - -public class ${CLASS}${METHOD}Body extends AMQMethodBody implements EncodableAMQDataBlock -{ - private static final AMQMethodBodyInstanceFactory factory = new AMQMethodBodyInstanceFactory() - { - public AMQMethodBody newInstance(byte major, byte minor, ByteBuffer in, long size) throws AMQFrameDecodingException - { - return new ${CLASS}${METHOD}Body(major, minor, in); - } - - public AMQMethodBody newInstance(byte major, byte minor, int clazzID, int methodID, ByteBuffer in, long size) throws AMQFrameDecodingException - { - return new ${CLASS}${METHOD}Body(major, minor, clazzID, methodID, in); - } - - }; - - public static AMQMethodBodyInstanceFactory getFactory() - { - return factory; - } - - public static HashMap classIdMap = new HashMap(); - public static HashMap methodIdMap = new HashMap(); - - private static void registerMethodId(byte major, byte minor, int methodId) - { - methodIdMap.put((0xff & (int) major) | ((0xff & (int) minor)<<8), methodId); - } - - private static void registerClassId(byte major, byte minor, int classId) - { - classIdMap.put((0xff & (int) major) | ((0xff & (int) minor)<<8), classId); - } - - - static - { - ${CLASS_ID_INIT} - ${METHOD_ID_INIT} - } - - // Fields declared in specification -%{FLIST} ${field_declaration} - - private final int _clazz; - private final int _method; - - - // Constructor - - public ${CLASS}${METHOD}Body(byte major, byte minor, ByteBuffer buffer) throws AMQFrameDecodingException - { - this(major, minor, getClazz(major,minor), getMethod(major,minor), buffer); - } - - public ${CLASS}${METHOD}Body(byte major, byte minor, int clazzID, int methodID, ByteBuffer buffer) throws AMQFrameDecodingException - { - super(major, minor); - _clazz = clazzID; - _method = methodID; -%{FLIST} ${mb_field_decode} - } - - public ${CLASS}${METHOD}Body(byte major, byte minor, int clazzID, int methodID -%{FLIST} ${mb_field_parameter_list} - ) - { - super(major, minor); - _clazz = getClazz(major,minor); - _method = getMethod(major,minor); -%{FLIST} ${mb_field_body_initialize} - } - - public int getClazz() - { - return _clazz; - } - - public int getMethod() - { - return _method; - } - - public static int getClazz(byte major, byte minor) - { - return classIdMap.get((0xff & (int) major) | ((0xff & (int) minor)<<8)); - } - - public static int getMethod(byte major, byte minor) - { - return methodIdMap.get((0xff & (int) major) | ((0xff & (int) minor)<<8)); - } - - - // Field methods -%{FLIST} ${mb_field_get_method} - - public int getBodySize() - { - int size = 0; -%{FLIST} ${mb_field_size} - return size; - } - - protected void writeMethodPayload(ByteBuffer buffer) - { -%{FLIST} ${mb_field_encode} - } - - public void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException - { -%{FLIST} ${mb_field_decode} - } - - public String toString() - { - StringBuffer buf = new StringBuffer(super.toString()); -%{FLIST} ${mb_field_to_string} - return buf.toString(); - } - - public static ${CLASS}${METHOD}Body createMethodBody(byte major, byte minor -%{FLIST} ${mb_field_parameter_list} - ) - { - return createMethodBody(major, minor, getClazz(major, minor), getMethod(major, minor) -%{FLIST} ${mb_field_passed_parameter_list} - ); - } - - public static ${CLASS}${METHOD}Body createMethodBody(byte major, byte minor, int clazzID, int methodID -%{FLIST} ${mb_field_parameter_list} - ) - { - return new ${CLASS}${METHOD}Body(major, minor, clazzID, methodID -%{FLIST} ${mb_field_passed_parameter_list} - ); - } - - public ${CLASS}${METHOD}Body copy() - { - return new ${CLASS}${METHOD}Body(major, minor, getClazz(major, minor), getMethod(major, minor) -%{FLIST} ${mb_field_passed_parameter_list} - ); - } -} diff --git a/cpp/gentools/templ.java/MethodRegistryClass.tmpl b/cpp/gentools/templ.java/MethodRegistryClass.tmpl deleted file mode 100644 index 12e6fe250e..0000000000 --- a/cpp/gentools/templ.java/MethodRegistryClass.tmpl +++ /dev/null @@ -1,125 +0,0 @@ -&{MainRegistry.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.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; - -public class MainRegistry -{ - private static final Logger _log = Logger.getLogger(MainRegistry.class); - - private static final int DEFAULT_MINOR_VERSION_COUNT = 10; - private static final int DEFAULT_MAJOR_VERSION_COUNT = 10; - - private static VersionSpecificRegistry[][] _specificRegistries = new VersionSpecificRegistry[DEFAULT_MAJOR_VERSION_COUNT][]; - - static - { -%{CLIST} ${reg_map_put_method} - } - - public static AMQMethodBody get(short classID, short methodID, byte major, byte minor, ByteBuffer in, long size) - throws AMQFrameDecodingException - { - VersionSpecificRegistry registry = getVersionSpecificRegistry(major, minor); - AMQMethodBodyInstanceFactory bodyFactory = registry.getMethodBody(classID,methodID); - - if (bodyFactory == null) - { - throw new AMQFrameDecodingException(_log, - "Unable to find a suitable decoder for class " + classID + " and method " + - methodID + " in AMQP version " + major + "-" + minor + "."); - } - return bodyFactory.newInstance(major, minor, in, size); - - - } - - public static VersionSpecificRegistry getVersionSpecificRegistry(byte major, byte minor) - { - try - { - return _specificRegistries[(int)major][(int)minor]; - } - catch (IndexOutOfBoundsException e) - { - return null; - } - catch (NullPointerException e) - { - return null; - } - - - } - - private static VersionSpecificRegistry addVersionSpecificRegistry(byte major, byte minor) - { - VersionSpecificRegistry[][] registries = _specificRegistries; - if(major >= registries.length) - { - _specificRegistries = new VersionSpecificRegistry[(int)major + 1][]; - System.arraycopy(registries, 0, _specificRegistries, 0, registries.length); - registries = _specificRegistries; - } - if(registries[major] == null) - { - registries[major] = new VersionSpecificRegistry[ minor >= DEFAULT_MINOR_VERSION_COUNT ? minor + 1 : DEFAULT_MINOR_VERSION_COUNT ]; - } - else if(registries[major].length <= minor) - { - VersionSpecificRegistry[] minorArray = registries[major]; - registries[major] = new VersionSpecificRegistry[ minor + 1 ]; - System.arraycopy(minorArray, 0, registries[major], 0, minorArray.length); - - } - - VersionSpecificRegistry newRegistry = new VersionSpecificRegistry(major,minor); - - registries[major][minor] = newRegistry; - - return newRegistry; - } - - private static void registerMethod(short classID, short methodID, byte major, byte minor, AMQMethodBodyInstanceFactory instanceFactory ) - { - VersionSpecificRegistry registry = getVersionSpecificRegistry(major,minor); - if(registry == null) - { - registry = addVersionSpecificRegistry(major,minor); - - } - - registry.registerMethod(classID, methodID, instanceFactory); - - } - - -} diff --git a/cpp/gentools/templ.java/PropertyContentHeaderClass.tmpl b/cpp/gentools/templ.java/PropertyContentHeaderClass.tmpl deleted file mode 100644 index 3c147cf6b6..0000000000 --- a/cpp/gentools/templ.java/PropertyContentHeaderClass.tmpl +++ /dev/null @@ -1,207 +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.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; - -public class ${CLASS}ContentHeaderProperties implements ContentHeaderProperties -{ - private static final Logger logger = Logger.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/cpp/gentools/templ.java/ProtocolVersionListClass.tmpl b/cpp/gentools/templ.java/ProtocolVersionListClass.tmpl deleted file mode 100644 index bc98e0c1ea..0000000000 --- a/cpp/gentools/templ.java/ProtocolVersionListClass.tmpl +++ /dev/null @@ -1,38 +0,0 @@ -&{ProtocolVersionList.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; - -public interface ProtocolVersionList -{ - public final int PROTOCOL_MAJOR = 0; - public final int PROTOCOL_MINOR = 1; - public final byte pv[][] = { -%{VLIST} ${protocol-version-list-entry} - }; -} diff --git a/cpp/gentools/xml-src/amqp-0.10.test.xml b/cpp/gentools/xml-src/amqp-0.10.test.xml deleted file mode 100644 index 5d3d80648b..0000000000 --- a/cpp/gentools/xml-src/amqp-0.10.test.xml +++ /dev/null @@ -1,4241 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - 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. - - - - - - The client attempted to transfer content larger than the server could accept - at the present time. The client may retry at a later time. - - - - - - An operator intervened to close the connection for some reason. The client - may retry at some later date. - - - - - - The client tried to work with an unknown virtual host. - - - - - - The client attempted to work with a server entity to which it has no - access due to security settings. - - - - - The client attempted to work with a server entity that does not exist. - - - - - The client attempted to work with a server entity to which it has no - access because another client is working with it. - - - - - - The client requested a method that was not allowed because some precondition - failed. - - - - - - The client sent a malformed frame that the server could not decode. This - strongly implies a programming error in the client. - - - - - - The client sent a frame that contained illegal values for one or more - fields. This strongly implies a programming error in the client. - - - - - - 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. - - - - - - The client attempted to work with a channel that had not been correctly - opened. This most likely indicates a fault in the client layer. - - - - - - 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. - - - - - - 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. - - - - - - The client tried to use functionality that is not implemented in the - server. - - - - - - 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. - - - - - - - - - - - - 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. - - - - - - - - - Identifier for the consumer, valid within the current connection. - - - - - - The server-assigned and channel-specific delivery tag - - - - 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. - - - - - The server MUST NOT use a zero value for delivery tags. Zero is reserved - for client use, meaning "all messages so far received". - - - - - - - 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. - - - - - - - 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. - - - - - - - - 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. - - - - - - If the no-local field is set the server will not send messages to the client that - published them. - - - - - - 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 - [.-_+!=:]. - - - - - - - - - - This string provides a set of peer properties, used for identification, debugging, and - general information. - - - - - - The queue name identifies the queue within the vhost. Queue names may consist of any - mixture of digits, letters, and underscores. - - - - - - - This indicates that the message has been previously delivered to this or - another client. - - - - 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. - - - 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. - - - - - 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. - - - - - - - The reply code. The AMQ reply codes are defined as constants at the start - of this formal specification. - - - - - - - The localised reply text. This text can be logged as an aid to resolving - issues. - - - - - - - - - - - - - - - - - - - - - - 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. - - - - 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 - - - - - - - - - - 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. - - - - - If the server cannot support the protocol specified in the protocol header, - it MUST close the socket connection without sending any response method. - - - The client sends a protocol header containing an invalid protocol name. - The server must respond by closing the connection. - - - - - The server MUST provide a protocol version that is lower than or equal to - that requested by the client in the protocol header. - - - 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. - - - - - If the client cannot handle the protocol version suggested by the server - it MUST close the socket connection. - - - 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. - - - - - - - - - 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. - - - This field should be renamed to "protocol version". - - - - - - 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". - - - This field should be renamed to "protocol revision". - - - - - - - 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. - - - Client connects to server and inspects the server properties. It checks for - the presence of the required fields. - - - - - - - A list of the security mechanisms that the server supports, delimited by spaces. - Currently ASL supports these mechanisms: PLAIN. - - - - - - - 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. - - - - The server MUST support at least the en_US locale. - - - Client connects to server and inspects the locales field. It checks for - the presence of the required locale(s). - - - - - - - - - This method selects a SASL security mechanism. ASL uses SASL (RFC2222) to - negotiate authentication and encryption. - - - - - - - - - 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. - - - - - - - A single security mechanisms selected by the client, which must be one of those - specified by the server. - - - - The client SHOULD authenticate using the highest-level security profile it - can handle from the list provided by the server. - - - - - 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. - - - 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). - - - - - - - - A block of opaque data passed to the security mechanism. The contents of this - data are defined by the SASL security mechanism. - - - - - - - A single message local selected by the client, which must be one of those - specified by the server. - - - - - - - - - - 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. - - - - - - - - Challenge information, a block of opaque binary data passed to the security - mechanism. - - - - - - - This method attempts to authenticate, passing a block of SASL data for the security - mechanism at the server side. - - - - - - - A block of opaque data passed to the security mechanism. The contents of this - data are defined by the SASL security mechanism. - - - - - - - - - - This method proposes a set of connection configuration values to the client. The - client can accept and/or adjust these. - - - - - - - - - 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. - - - - - - 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. - - - - 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. - - - Client connects to server and sends a large properties field, creating a frame - of frame-min-size octets. The server must accept this frame. - - - - - - - - The delay, in seconds, of the connection heartbeat that the server wants. - Zero means the server does not want a heartbeat. - - - - - - - This method sends the client's connection tuning parameters to the server. - Certain fields are negotiated, others provide capability information. - - - - - - - The maximum total number of channels that the client will use per connection. - - - - 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. - - - - - - - - - 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. - - - - 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. - - - - - 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. - - - - - - - The delay, in seconds, of the connection heartbeat that the client wants. Zero - means the client does not want a heartbeat. - - - - - - - - - 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. - - - - - - - - - - - The name of the virtual host to work with. - - - - 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. - - - - - The server SHOULD verify that the client has permission to access the - specified virtual host. - - - - - - - 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. - - - - - - 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. - - - - 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. - - - - - - - - This method signals to the client that the connection is ready for use. - - - - - - - - This method redirects the client to another server, based on the requested virtual - host and/or capabilities. - - - - 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. - - - - - - 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. - - - - - - - - - - - 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. - - - - - After sending this method any received method except the Close-OK method MUST - be discarded. - - - - - - - - - - - - - When the close is provoked by a method exception, this is the class of the - method. - - - - - - When the close is provoked by a method exception, this is the ID of the method. - - - - - - - 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. - - - - A peer that detects a socket closure without having received a Close-Ok - handshake method SHOULD log the error. - - - - - - - - - - - - The channel class provides methods for a client to establish a channel to a - server and for both peers to operate the channel thereafter. - - - - 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 - - - - - - - - - - This method opens a channel to the server. - - - - The client MUST NOT use this method on an alread-opened channel. - - - Client opens a channel and then reopens the same channel. - - - - - - - Configures out-of-band transfers on this channel. The syntax and meaning of this - field will be formally defined at a later date. - - - - - - - - This method signals to the client that the channel is ready for use. - - - - - - - - - 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. - - - - - 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. - - - - - - When sending content frames, a peer SHOULD monitor the channel for incoming - methods and respond to a Channel.Flow as rapidly as possible. - - - - - - 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. - - - - - - 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. - - - - - - - - - - - If 1, the peer starts sending content frames. If 0, the peer stops sending - content frames. - - - - - - - Confirms to the peer that a flow command was received and processed. - - - - - - 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. - - - - - - - - - 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. - - - - - - - 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). - - - - - - - - - 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. - - - - - - After sending this method any received method except the Close-OK method MUST - be discarded. - - - - - - - - - - - - - When the close is provoked by a method exception, this is the class of the - method. - - - - - - When the close is provoked by a method exception, this is the ID of the method. - - - - - - - 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. - - - - A peer that detects a socket closure without having received a Channel.Close-Ok - handshake method SHOULD log the error. - - - - - - - - - - - - - - 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. - - - - access = C:REQUEST S:REQUEST-OK - - - - - - - - - - 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. - - - - - - - - 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. - - - - 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. - - - Client specifies an undefined realm. - - - - - - - Request exclusive access to the realm, meaning that this will be the only - channel that uses the realm's resources. - - - - 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. - - - Client opens two channels and requests exclusive access to the same realm. - - - - - - 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. - - - - - Request message active access to the specified access realm. Active access lets - a client get create and delete resources in the realm. - - - - - Request write access to the specified access realm. Write access lets a client - publish messages to all exchanges in the realm. - - - - - Request read access to the specified access realm. Read access lets a client - consume messages from queues in the realm. - - - - - - - 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. - - - - The client MUST NOT use access tickets except within the same channel as - originally granted. - - - Client opens two channels, requests a ticket on one channel, and then - tries to use that ticket in a seconc channel. - - - - - - - - - - - - Exchanges match and distribute messages across queues. Exchanges can be configured in - the server or created at runtime. - - - - exchange = C:DECLARE S:DECLARE-OK - / C:DELETE S:DELETE-OK - - - - - - - - The server MUST implement these standard exchange types: fanout, direct. - - - Client attempts to declare an exchange with each of these standard types. - - - - - The server SHOULD implement these standard exchange types: topic, headers. - - - Client attempts to declare an exchange with each of these standard types. - - - - - 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. - - - 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). - - - - - The server MUST predeclare a direct exchange to act as the default exchange - for content Publish methods and for default queue bindings. - - - 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. - - - - - 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. - - - - - The server MAY implement other exchange types as wanted. - - - - - - - - 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. - - - - The server SHOULD support a minimum of 16 exchanges per virtual host and - ideally, impose no limit except as defined by available resources. - - - 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. - - - - - - - - - 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. - - - - 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. - - - Client creates access ticket with wrong access rights and attempts to use - in this method. - - - - - - - - Exchange names starting with "amq." are reserved for predeclared and - standardised exchanges. The client MUST NOT attempt to create an exchange - starting with "amq.". - - - TODO. - - - - - - - - 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. - - - - 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. - - - TODO. - - - - - The client MUST NOT attempt to create an exchange with a type that the - server does not support. - - - TODO. - - - - - - - - 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. - - - - If set, and the exchange does not already exist, the server MUST raise a - channel exception with reply code 404 (not found). - - - TODO. - - - - - - - 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. - - - - The server MUST support both durable and transient exchanges. - - - TODO. - - - - - The server MUST ignore the durable field if the exchange already exists. - - - TODO. - - - - - - - - If set, the exchange is deleted when all queues have finished using it. - - - - The server MUST ignore the auto-delete field if the exchange already - exists. - - - TODO. - - - - - - - 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. - - - - - - 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. - - - - - - - This method confirms a Declare method and confirms the name of the exchange, - essential for automatically-named exchanges. - - - - - - - - - This method deletes an exchange. When an exchange is deleted all queue bindings on - the exchange are cancelled. - - - - - - - - - The client MUST provide a valid access ticket giving "active" access - rights to the exchange's access realm. - - - Client creates access ticket with wrong access rights and attempts to use - in this method. - - - - - - - - The client MUST NOT attempt to delete an exchange that does not exist. - - - - - - - - - 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. - - - - - - This method confirms the deletion of an exchange. - - - - - - - - - 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. - - - - queue = C:DECLARE S:DECLARE-OK - / C:BIND S:BIND-OK - / C:PURGE S:PURGE-OK - / C:DELETE S:DELETE-OK - - - - - - - - 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. - - - 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. - - - - - - - - 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. - - - - - The server MUST create a default binding for a newly-created queue to the - default exchange, which is an exchange of type 'direct'. - - - 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. - - - - - - - The server SHOULD support a minimum of 256 queues per virtual host and ideally, - impose no limit except as defined by available resources. - - - Client attempts to create as many queues as it can until the server reports - an error. The resulting count must at least be 256. - - - - - - - - - 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. - - - - The client MUST provide a valid access ticket giving "active" access to - the realm in which the queue exists or will be created. - - - Client creates access ticket with wrong access rights and attempts to use - in this method. - - - - - - - - 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. - - - Client attempts to create several queues with an empty name. The client then - verifies that the server-assigned names are unique and different. - - - - - 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. - - - A client attempts to create a queue with a name starting with "amq." and with - the passive option set to zero. - - - - - - - - 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. - - - - 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. - - - 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. - - - - - - - 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. - - - - The server MUST recreate the durable queue after a restart. - - - - 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. - - - - - The server MUST support both durable and transient queues. - - A client creates two named queues, one durable and one transient. - - - - - The server MUST ignore the durable field if the queue already exists. - - 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. - - - - - - - - Exclusive queues may only be consumed from by the current connection. Setting - the 'exclusive' flag always implies 'auto-delete'. - - - - - - The server MUST support both exclusive (private) and non-exclusive (shared) - queues. - - - A client creates two named queues, one exclusive and one non-exclusive. - - - - - - - The client MAY NOT attempt to declare any existing and exclusive queue - on multiple connections. - - - A client declares an exclusive named queue. A second client on a different - connection attempts to declare a queue of the same name. - - - - - - - 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. - - - - - - The server MUST ignore the auto-delete field if the queue already exists. - - - 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. - - - - - - - - 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. - - - - - - - This method confirms a Declare method and confirms the name of the queue, essential - for automatically-named queues. - - - - - - - Reports the name of the queue. If the server generated a queue name, this field - contains that name. - - - - - - - Reports the number of messages in the queue, which will be zero for - newly-created queues. - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - A client binds a named queue to an exchange. The client then repeats the bind - (with identical arguments). - - - - - - - If a bind fails, the server MUST raise a connection exception. - - TODO - - - - - - - The server MUST NOT allow a durable queue to bind to a transient exchange. - - - 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. - - - - - - - Bindings for durable queues are automatically durable and the server SHOULD - restore such bindings after a server restart. - - - 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. - - - - - - - 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). - - - A client attempts to bind a named queue to an internal exchange. - - - - - - - The server SHOULD support at least 4 bindings per queue, and ideally, impose no - limit except as defined by available resources. - - - A client creates a named queue and attempts to bind it to 4 different non-internal - exchanges. - - - - - - - - - - The client provides a valid access ticket giving "active" access rights to the - queue's access realm. - - - - - - 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. - - - - - A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e. - empty queue name) to an exchange. - - - A client attempts to bind with an unnamed (empty) queue name to an exchange. - - - - - - - A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously - declared) to an exchange. - - - A client attempts to bind an undeclared queue name to an exchange. - - - - - - - - - A client MUST NOT be allowed to bind a queue to a non-existent exchange. - - - A client attempts to bind an named queue to a undeclared exchange. - - - - - - - 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. - - - - - - A set of arguments for the binding. The syntax and semantics of these arguments - depends on the exchange class. - - - - - - This method confirms that the bind was successful. - - - - - - - - - This method removes all messages from a queue. It does not cancel consumers. Purged - messages are deleted without any formal "undo" mechanism. - - - - - A call to purge MUST result in an empty queue. - - - - - - On transacted channels the server MUST not purge messages that have already been - sent to a client but not yet acknowledged. - - - - - - - - - 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. - - - - - - - - - The access ticket must be for the access realm that holds the queue. - - - - 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. - - - - - - - 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. - - - - - 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). - - - - - - - - - The queue MUST exist. Attempting to purge a non-existing queue MUST cause a - channel exception. - - - - - - - This method confirms the purge of a queue. - - - - - Reports the number of messages purged. - - - - - - - - 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. - - - - - - - - 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. - - - - - - - - - - The client provides a valid access ticket giving "active" access rights to the - queue's access realm. - - - - - - 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. - - - - - 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). - - - - - - - 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). - - - - - - - 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. - - - - - The server MUST respect the if-unused flag when deleting a queue. - - - - - - If set, the server will only delete the queue if it has no messages. - - - - If the queue is not empty the server MUST raise a channel exception with - reply code 406 (precondition failed). - - - - - - - This method confirms the deletion of a queue. - - - - - Reports the number of messages purged. - - - - - - - - - The Basic class provides methods that support an industry-standard messaging model. - - - - 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 - - - - - - - - - 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. - - - 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. - - - - - - - The server MUST NOT discard a persistent basic message in case of a queue - overflow. - - - Create a queue overflow situation with persistent messages and verify that - messages do not get lost (presumably the server will write them to disk). - - - - - - The server MAY use the Channel.Flow method to slow or stop a basic message - publisher when necessary. - - - Create a queue overflow situation with non-persistent messages and verify - whether the server responds with Channel.Flow or not. Repeat with persistent - messages. - - - - - - - The server MAY overflow non-persistent basic messages to persistent - storage. - - - - - - - The server MAY discard or dead-letter non-persistent basic messages on a - priority basis if the queue size exceeds some configured limit. - - - - - - - - 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. - - - 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. - - - - - - The server MAY implement up to 10 priority levels. - - - 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. - - - - - - - The server MUST deliver messages of the same priority in order irrespective of - their individual persistence. - - - 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. - - - - - - - The server MUST support automatic acknowledgements on Basic content, i.e. - consumers with the no-ack field set to FALSE. - - - 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. - - - - - - The server MUST support explicit acknowledgements on Basic content, i.e. - consumers with the no-ack field set to TRUE. - - - 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. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - - - 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. - - - - - 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. - - - Define a QoS prefetch-size limit and send a single message that exceeds - that limit. Verify that the message arrives correctly. - - - - - - - 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. - - - - - The server may send less data in advance than allowed by the client's - specified prefetch windows but it MUST NOT send more. - - - 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. - - - - - - - By default the QoS settings apply to the current channel only. If this field is - set, they are applied to the entire connection. - - - - - - - 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. - - - - - - - - - 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. - - - - - - The server SHOULD support at least 16 consumers per queue, and ideally, impose - no limit except as defined by available resources. - - - 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. - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - Attempt to create a consumer with an invalid (non-zero) access ticket. - - - - - - - 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. - - - - If the queue name is empty the client MUST have previously declared a - queue using this channel. - - - Attempt to create a consumer with an empty queue name and no previously - declared queue on the channel. - - - - - - - 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. - - - - The client MUST NOT specify a tag that refers to an existing consumer. - - - Attempt to create two consumers with the same non-empty tag. - - - - - 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. - - - 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). - - - - - - - - - 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. - - - - - - - - - - - - - - - - - - Request exclusive consumer access, meaning only this consumer can access the - queue. - - - - - The client MAY NOT gain exclusive access to a queue that already has - active consumers. - - - 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. - - - - - - - - - - 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. - - - - - Holds the consumer tag specified by the client or provided by the server. - - - - - - - - - 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. - - - - - If the queue does not exist the server MUST ignore the cancel method, so - long as the consumer tag is valid for that channel. - - - TODO. - - - - - - - - - - - - This method confirms that the cancellation was completed. - - - - - - - - - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "write" access rights - to the access realm for the exchange. - - - TODO. - - - - - - - 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. - - - - - - The server MUST accept a blank exchange name to mean the default exchange. - - - TODO. - - - - - - - If the exchange was declared as an internal exchange, the server MUST raise - a channel exception with a reply code 403 (access refused). - - - TODO. - - - - - - - The exchange MAY refuse basic content in which case it MUST raise a channel - exception with reply code 540 (not implemented). - - - TODO. - - - - - - - Specifies the routing key for the message. The routing key is used for routing - messages depending on the exchange configuration. - - - - - - 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. - - - - - The server SHOULD implement the mandatory flag. - - - TODO. - - - - - - - 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. - - - - - The server SHOULD implement the immediate flag. - - - TODO. - - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - - 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. - - - - - - - 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. - - - TODO. - - - - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - 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. - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - TODO. - - - - - - - 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. - - - - 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). - - - TODO. - - - - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - If empty, the message was published to the default exchange. - - - - - Specifies the routing key name specified when the message was published. - - - - - 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. - - - - - - - This method tells the client that the queue has no messages available for the - client. - - - - - - - - For use by cluster applications, should not be used by client applications. - - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - TODO. - - - - - - - - - - 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. - - - - - - 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). - - - - - - - The server SHOULD interpret this method as meaning that the client is unable to - process the message at this time. - - - TODO. - - - - - - - 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. - - - TODO. - - - - - - - - - - If this field is zero, the message will be discarded. If this bit is 1, the - server will attempt to requeue the message. - - - - - - - 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. - - - TODO. - - - - - - - - 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. - - - - - The server MUST set the redelivered flag on all messages that are resent. - - - TODO. - - - - - - The server MUST raise a channel exception if this is called on a transacted - channel. - - - TODO. - - - - - - - - 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. - - - - - - - - - - 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. - - - - 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 - - - - - - - - The server MUST make a best-effort to hold file messages on a reliable storage - mechanism. - - - - - - - - - - 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. - - - - - - - - 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. - - - - - - The server MUST support both automatic and explicit acknowledgements on file - content. - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - - - - The server MAY send less data in advance than allowed by the client's - specified prefetch windows but it MUST NOT send more. - - - - - - - By default the QoS settings apply to the current channel only. If this field is - set, they are applied to the entire connection. - - - - - - - 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. - - - - - - - - - - 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. - - - - - 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. - - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - - - - - 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. - - - - - 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). - - - - - - - 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. - - - - - - 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). - - - - - - - - - - - Request exclusive consumer access, meaning only this consumer can access the - queue. - - - - - - 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). - - - - - - - - This method provides the client with a consumer tag which it MUST use in methods - that work with the consumer. - - - - - - Holds the consumer tag specified by the client or provided by the server. - - - - - - - - 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. - - - - - - - - - - - This method confirms that the cancellation was completed. - - - - - - - - - - - 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. - - - - - - - - - - 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.). - - - - - - 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. - - - - - The sender MUST accurately fill the content-size field. Zero-length content - is permitted. - - - - - - - - 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. - - - - - - - - - - The amount of previously-staged content in octets. For a new message this will - be zero. - - - - - The sender MUST start sending data from this octet offset in the message, - counting from zero. - - - - - - - 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. - - - - - - - - - - This method stages the message, sending the message content to the recipient from - the octet offset specified in the Open-Ok method. - - - - - - - - - - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "write" access rights - to the access realm for the exchange. - - - - - - - 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. - - - - - The server MUST accept a blank exchange name to mean the default exchange. - - - - - - 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. - - - - - - - - The exchange MAY refuse file content in which case it MUST respond with a - reply code 540 (not implemented) and raise a channel exception. - - - - - - - Specifies the routing key for the message. The routing key is used for routing - messages depending on the exchange configuration. - - - - - - 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. - - - - - The server SHOULD implement the mandatory flag. - - - - - - 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. - - - - - The server SHOULD implement the immediate flag. - - - - - - 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. - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - 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. - - - - - - 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. - - - - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - 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. - - - - - - - - - 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. - - - - - - - - - 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. - - - - - 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. - - - - - - - - - - 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. - - - - - The server SHOULD interpret this method as meaning that the client is unable to - process the message at this time. - - - - - - - - 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. - - - - - - - - - - If this field is zero, the message will be discarded. If this bit is 1, the - server will attempt to requeue the message. - - - - - - 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. - - - - - - - - - - - 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. - - - - stream = C:QOS S:QOS-OK - / C:CONSUME S:CONSUME-OK - / C:CANCEL S:CANCEL-OK - / C:PUBLISH content - / S:RETURN - / S:DELIVER content - - - - - - - - The server SHOULD discard stream messages on a priority basis if the queue size - exceeds some configured limit. - - - - - - - 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. - - - - - - 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. - - - - - - - - - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - - - - 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. - - - - - - 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. - - - - - - - By default the QoS settings apply to the current channel only. If this field is - set, they are applied to the entire connection. - - - - - - - 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. - - - - - - - - - - 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. - - - - - 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. - - - - - - 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. - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - - - - - 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. - - - - - 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). - - - - - - - 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. - - - - - - 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). - - - - - - - - - Request exclusive consumer access, meaning only this consumer can access the - queue. - - - - - - - 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). - - - - - - - - This method provides the client with a consumer tag which it may use in methods that - work with the consumer. - - - - - - Holds the consumer tag specified by the client or provided by the server. - - - - - - - - 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. - - - - - - - - - - - This method confirms that the cancellation was completed. - - - - - - - - - - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "write" access rights - to the access realm for the exchange. - - - - - - - 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. - - - - - The server MUST accept a blank exchange name to mean the default exchange. - - - - - - 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. - - - - - - The exchange MAY refuse stream content in which case it MUST respond with a - reply code 540 (not implemented) and raise a channel exception. - - - - - - - Specifies the routing key for the message. The routing key is used for routing - messages depending on the exchange configuration. - - - - - - 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. - - - - - The server SHOULD implement the mandatory flag. - - - - - - 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. - - - - - The server SHOULD implement the immediate flag. - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - - Specifies the name of the queue that the message came from. Note that a single - channel can start many consumers on different queues. - - - - - - - - - - - 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. - - - - - - - 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. - - - - - tx = C:SELECT S:SELECT-OK - / C:COMMIT S:COMMIT-OK - / C:ROLLBACK S:ROLLBACK-OK - - - - - - - - - - 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. - - - - - - - - This method confirms to the client that the channel was successfully set to use - standard transactions. - - - - - - - - - This method commits all messages published and acknowledged in the current - transaction. A new transaction starts immediately after a commit. - - - - - - - - This method confirms to the client that the commit succeeded. Note that if a commit - fails, the server raises a channel exception. - - - - - - - - - This method abandons all messages published and acknowledged in the current - transaction. A new transaction starts immediately after a rollback. - - - - - - - - This method confirms to the client that the rollback succeeded. Note that if an - rollback fails, the server raises a channel exception. - - - - - - - - - - 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. - - - - dtx = C:SELECT S:SELECT-OK - C:START S:START-OK - - - - - - - - - - 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. - - - - - - - - This method confirms to the client that the channel was successfully set to use - distributed transactions. - - - - - - - - - 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. - - - - - - The distributed transaction key. This identifies the transaction so that the - AMQP server can coordinate with the distributed transaction coordinator. - - - - - - - - This method confirms to the client that the transaction started. Note that if a - start fails, the server raises a channel exception. - - - - - - - - - - The tunnel methods are used to send blocks of binary data - which can be serialised AMQP - methods or other protocol frames - between AMQP peers. - - - - tunnel = C:REQUEST - / S:REQUEST - - - - - - - - - - - - - - - - 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. - - - - - This field table holds arbitrary meta-data that the sender needs to - pass to the recipient. - - - - - diff --git a/cpp/gentools/xml-src/amqp-0.8.test.xml b/cpp/gentools/xml-src/amqp-0.8.test.xml deleted file mode 100644 index b0adf31828..0000000000 --- a/cpp/gentools/xml-src/amqp-0.8.test.xml +++ /dev/null @@ -1,3959 +0,0 @@ - - - - - - - - AMQ Protocol 0.80 - - - - - - - - - - - - - - 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. - - - 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. - - - The client attempted to transfer content larger than the server - could accept at the present time. The client may retry at a later - time. - - - An operator intervened to close the connection for some reason. - The client may retry at some later date. - - - The client tried to work with an unknown virtual host or cluster. - - - The client attempted to work with a server entity to which it has - no due to security settings. - - - The client attempted to work with a server entity that does not exist. - - - The client attempted to work with a server entity to which it has - no access because another client is working with it. - - - The client sent a malformed frame that the server could not decode. - This strongly implies a programming error in the client. - - - The client sent a frame that contained illegal values for one or more - fields. This strongly implies a programming error in the client. - - - 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. - - - The client attempted to work with a channel that had not been - correctly opened. This most likely indicates a fault in the client - layer. - - - 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. - - - 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. - - - The client tried to use functionality that is not implemented in the - server. - - - 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. - - - - access ticket granted by server - - 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. - - - - - - consumer tag - - Identifier for the consumer, valid within the current connection. - - - 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. - - - - server-assigned delivery tag - - The server-assigned and channel-specific delivery tag - - - 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. - - - The server MUST NOT use a zero value for delivery tags. Zero is - reserved for client use, meaning "all messages so far received". - - - - exchange name - - 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. - - - - -list of known hosts - -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. - - -The server MAY leave this field empty if it knows of no other -hosts than itself. - - - - - no acknowledgement needed - - 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. - - - - do not deliver own messages - - If the no-local field is set the server will not send messages to - the client that published them. - - - - - 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 [.-_+!=:]. - - - - - - - -This string provides a set of peer properties, used for -identification, debugging, and general information. - - -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. - - - - queue name - - The queue name identifies the queue within the vhost. Queue - names may consist of any mixture of digits, letters, and - underscores. - - - - - message is being redelivered - - This indicates that the message has been previously delivered to - this or another client. - - - 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. - - - 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. - - - -reply code from server - - The reply code. The AMQ reply codes are defined in AMQ RFC 011. - - - - -localised reply text - - The localised reply text. This text can be logged as an aid to - resolving issues. - - - - - - work with socket connections - - 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. - - - 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 - - - - - - start connection negotiation - - 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. - - - If the client cannot handle the protocol version suggested by the - server it MUST close the socket connection. - - - 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. - - - - - protocol major version - - The protocol major version that the server agrees to use, which - cannot be higher than the client's major version. - - - - protocol major version - - The protocol minor version that the server agrees to use, which - cannot be higher than the client's minor version. - - - - server properties - - - available security mechanisms - - A list of the security mechanisms that the server supports, delimited - by spaces. Currently ASL supports these mechanisms: PLAIN. - - - - - - available message locales - - 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. - - - All servers MUST support at least the en_US locale. - - - - - - select security mechanism and locale - - This method selects a SASL security mechanism. ASL uses SASL - (RFC2222) to negotiate authentication and encryption. - - - - client properties - - - selected security mechanism - - A single security mechanisms selected by the client, which must be - one of those specified by the server. - - - The client SHOULD authenticate using the highest-level security - profile it can handle from the list provided by the server. - - - 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. - - - - - security response data - - 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. - - - - - selected message locale - - A single message local selected by the client, which must be one - of those specified by the server. - - - - - - - security mechanism challenge - - 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. - - - - - security challenge data - - Challenge information, a block of opaque binary data passed to - the security mechanism. - - - - - - security mechanism response - - This method attempts to authenticate, passing a block of SASL data - for the security mechanism at the server side. - - - - security response data - - A block of opaque data passed to the security mechanism. The contents - of this data are defined by the SASL security mechanism. - - - - - - - propose connection tuning parameters - - This method proposes a set of connection configuration values - to the client. The client can accept and/or adjust these. - - - - - proposed maximum channels - - 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. - - - - proposed maximum frame size - - 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. - - - 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. - - - - desired heartbeat delay - - The delay, in seconds, of the connection heartbeat that the server - wants. Zero means the server does not want a heartbeat. - - - - - negotiate connection tuning parameters - - This method sends the client's connection tuning parameters to the - server. Certain fields are negotiated, others provide capability - information. - - - - negotiated maximum channels - - The maximum total number of channels that the client will use - per connection. May not be higher than the value specified by - the server. - - - The server MAY ignore the channel-max value or MAY use it for - tuning its resource allocation. - - - - - - negotiated maximum frame size - - 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. - - - 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. - - - - desired heartbeat delay - - The delay, in seconds, of the connection heartbeat that the client - wants. Zero means the client does not want a heartbeat. - - - - - - open connection to virtual host - - 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 client MUST open the context before doing any work on the - connection. - - - - - - virtual host name - - - The name of the virtual host to work with. - - - 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. - - - The server SHOULD verify that the client has permission to access - the specified virtual host. - - - 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. - - - - required capabilities - - 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. - - - - insist on connecting to server - - 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. - - - When the client uses the insist option, the server SHOULD accept - the client connection unless it is technically unable to do so. - - - - - signal that the connection is ready - - This method signals to the client that the connection is ready for - use. - - - - - - asks the client to use a different server - - This method redirects the client to another server, based on the - requested virtual host and/or capabilities. - - - 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. - - - - server to connect to - - 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. - - - - - - - - request a connection close - - 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. - - - After sending this method any received method except the Close-OK - method MUST be discarded. - - - 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. - - - 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. - - - - - - - - failing method class - - When the close is provoked by a method exception, this is the - class of the method. - - - - failing method ID - - When the close is provoked by a method exception, this is the - ID of the method. - - - - - confirm a connection close - - 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. - - - A peer that detects a socket closure without having received a - Close-Ok handshake method SHOULD log the error. - - - - - - - - work with channels - - 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. - - - 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 - - - - - - open a channel for use - - This method opens a virtual connection (a channel). - - - This method MUST NOT be called when the channel is already open. - - - - - out-of-band settings - - Configures out-of-band transfers on this channel. The syntax and - meaning of this field will be formally defined at a later date. - - - - - - signal that the channel is ready - - This method signals to the client that the channel is ready for use. - - - - - - enable/disable flow from peer - - 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. - - - 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. - - - 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. - - - 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. - - - The peer that requests a Channel.Flow method MAY disconnect and/or - ban a peer that does not respect the request. - - - - - - start/stop content frames - - If 1, the peer starts sending content frames. If 0, the peer - stops sending content frames. - - - - - confirm a flow method - - Confirms to the peer that a flow command was received and processed. - - - - - current flow setting - - 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. - - - - - - send a non-fatal warning message - - 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. - - - - - - detailed information for warning - - 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). - - - - - - request a channel close - - 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. - - - After sending this method any received method except - Channel.Close-OK MUST be discarded. - - - 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.. - - - - - - - - failing method class - - When the close is provoked by a method exception, this is the - class of the method. - - - - failing method ID - - When the close is provoked by a method exception, this is the - ID of the method. - - - - - confirm a channel close - - 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. - - - A peer that detects a socket closure without having received a - Channel.Close-Ok handshake method SHOULD log the error. - - - - - - - - work with access tickets - - 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. - - - access = C:REQUEST S:REQUEST-OK - - - - - - request an access ticket - - 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. - - - 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). - - - 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. - - - - - name of requested realm - - If the specified realm is not known to the server, the server - must raise a channel exception with reply code 402 (invalid - path). - - - - request exclusive access - - 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. - - - - request passive access - - 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. - - - - request active access - - Request message active access to the specified access realm. - Acvtive access lets a client get create and delete resources in - the realm. - - - - request write access - - Request write access to the specified access realm. Write access - lets a client publish messages to all exchanges in the realm. - - - - request read access - - Request read access to the specified access realm. Read access - lets a client consume messages from queues in the realm. - - - - - grant access to server resources - - 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. - - - The client MUST NOT use access tickets except within the same - channel as originally granted. - - - The server MUST isolate access tickets per channel and treat an - attempt by a client to mix these as a connection exception. - - - - - - - - work with exchanges - - Exchanges match and distribute messages across queues. Exchanges can be - configured in the server or created at runtime. - - - exchange = C:DECLARE S:DECLARE-OK - / C:DELETE S:DELETE-OK - - - - - amq_exchange_19 - 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. - - - amq_exchange_20 - The server SHOULD implement the topic exchange type, and predeclare - the corresponding exchange named amq.topic in each virtual host. - - - amq_exchange_21 - 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). - - - amq_exchange_22 - 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. - - - - declare exchange, create if needed - - 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. - - - amq_exchange_23 - The server SHOULD support a minimum of 16 exchanges per virtual host - and ideally, impose no limit except as defined by available resources. - - - - - - 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. - - - 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. - - - - - amq_exchange_15 - 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). - - - - - exchange type - - 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. - - - amq_exchange_16 - If the exchange already exists with a different type, the server - MUST raise a connection exception with a reply code 507 (not allowed). - - - amq_exchange_18 - If the server does not support the requested exchange type it MUST - raise a connection exception with a reply code 503 (command invalid). - - - - - do not create exchange - - 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. - - - amq_exchange_05 - If set, and the exchange does not already exist, the server MUST - raise a channel exception with reply code 404 (not found). - - - - request a durable exchange - - 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. - - - amq_exchange_24 - The server MUST support both durable and transient exchanges. - - - The server MUST ignore the durable field if the exchange already - exists. - - - - auto-delete when unused - - If set, the exchange is deleted when all queues have finished - using it. - - - amq_exchange_02 - 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. - - - amq_exchange_25 - The server MUST ignore the auto-delete field if the exchange already - exists. - - - - create internal exchange - - 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. - - - - - do not send a reply method - - 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. - - - - - arguments for declaration - - 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. - - - - - confirms an exchange declaration - - This method confirms a Declare method and confirms the name of the - exchange, essential for automatically-named exchanges. - - - - - - delete an exchange - - This method deletes an exchange. When an exchange is deleted all queue - bindings on the exchange are cancelled. - - - - - - The client MUST provide a valid access ticket giving "active" - access rights to the exchange's access realm. - - - - - amq_exchange_11 - The exchange MUST exist. Attempting to delete a non-existing exchange - causes a channel exception. - - - - - delete only if unused - - 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. - - - amq_exchange_12 - If set, the server SHOULD delete the exchange but only if it has - no queue bindings. - - - amq_exchange_13 - If set, the server SHOULD raise a channel exception if the exchange is in - use. - - - - - do not send a reply method - - 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. - - - - - - confirm deletion of an exchange - - This method confirms the deletion of an exchange. - - - - - - - work with queues - - - 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. - - - queue = C:DECLARE S:DECLARE-OK - / C:BIND S:BIND-OK - / C:PURGE S:PURGE-OK - / C:DELETE S:DELETE-OK - - - - - amq_queue_33 - 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. - - - - declare queue, create if needed - - 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. - - - amq_queue_34 - The server MUST create a default binding for a newly-created queue - to the default exchange, which is an exchange of type 'direct'. - - - amq_queue_35 - The server SHOULD support a minimum of 256 queues per virtual host - and ideally, impose no limit except as defined by available resources. - - - - - - 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. - - - 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. - - - - - amq_queue_10 - 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. - - - amq_queue_32 - 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). - - - - - do not create queue - - 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. - - - amq_queue_05 - 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. - - - - request a durable queue - - 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. - - - amq_queue_03 - The server MUST recreate the durable queue after a restart. - - - amq_queue_36 - The server MUST support both durable and transient queues. - - - amq_queue_37 - The server MUST ignore the durable field if the queue already - exists. - - - - request an exclusive queue - - Exclusive queues may only be consumed from by the current connection. - Setting the 'exclusive' flag always implies 'auto-delete'. - - - amq_queue_38 - The server MUST support both exclusive (private) and non-exclusive - (shared) queues. - - - amq_queue_04 - The server MUST raise a channel exception if 'exclusive' is specified - and the queue already exists and is owned by a different connection. - - - - auto-delete queue when unused - - 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. - - - amq_queue_02 - 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. - - - amq_queue_31 - The server MUST ignore the auto-delete field if the queue already - exists. - - - - do not send a reply method - - 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. - - - - - arguments for declaration - - 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. - - - - - confirms a queue definition - - This method confirms a Declare method and confirms the name of the - queue, essential for automatically-named queues. - - - - - Reports the name of the queue. If the server generated a queue - name, this field contains that name. - - - - - number of messages in queue - - Reports the number of messages in the queue, which will be zero - for newly-created queues. - - - - number of consumers - - 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. - - - - - - bind queue to an exchange - - 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. - - - amq_queue_25 - 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. - - - amq_queue_39 - If a bind fails, the server MUST raise a connection exception. - - - amq_queue_12 - 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. - - - amq_queue_13 - Bindings for durable queues are automatically durable and the - server SHOULD restore such bindings after a server restart. - - - amq_queue_17 - 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). - - - amq_queue_40 - The server SHOULD support at least 4 bindings per queue, and - ideally, impose no limit except as defined by available resources. - - - - - - The client provides a valid access ticket giving "active" - access rights to the queue's access realm. - - - - - - 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. - - - 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). - - - If the queue does not exist the server MUST raise a channel exception - with reply code 404 (not found). - - - - - The name of the exchange to bind to. - - amq_queue_14 - If the exchange does not exist the server MUST raise a channel - exception with reply code 404 (not found). - - - - message routing key - - 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. - - - - - do not send a reply method - - 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. - - - - - arguments for binding - - A set of arguments for the binding. The syntax and semantics of - these arguments depends on the exchange class. - - - - - confirm bind successful - - This method confirms that the bind was successful. - - - - - - purge a queue - - This method removes all messages from a queue. It does not cancel - consumers. Purged messages are deleted without any formal "undo" - mechanism. - - - amq_queue_15 - A call to purge MUST result in an empty queue. - - - amq_queue_41 - On transacted channels the server MUST not purge messages that have - already been sent to a client but not yet acknowledged. - - - amq_queue_42 - 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. - - - - - - The access ticket must be for the access realm that holds the - queue. - - - 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. - - - - - 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. - - - 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). - - - The queue must exist. Attempting to purge a non-existing queue - causes a channel exception. - - - - - do not send a reply method - - 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. - - - - - confirms a queue purge - - This method confirms the purge of a queue. - - - - number of messages purged - - Reports the number of messages purged. - - - - - - delete a queue - - 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. - - - amq_queue_43 - 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. - - - - - - The client provides a valid access ticket giving "active" - access rights to the queue's access realm. - - - - - - 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. - - - 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). - - - The queue must exist. Attempting to delete a non-existing queue - causes a channel exception. - - - - - delete only if unused - - 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. - - - amq_queue_29 - amq_queue_30 - The server MUST respect the if-unused flag when deleting a queue. - - - - delete only if empty - amq_queue_27 - - 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. - - - - do not send a reply method - - 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. - - - - - - confirm deletion of a queue - - This method confirms the deletion of a queue. - - - - number of messages purged - - Reports the number of messages purged. - - - - - - - work with basic content - - The Basic class provides methods that support an industry-standard - messaging model. - - - - 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 - - - - - - - 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. - - - 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. - - - 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. - - - 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. - - - The server MUST deliver messages of the same priority in order - irrespective of their individual persistence. - - - The server MUST support both automatic and explicit acknowledgements - on Basic content. - - - - - - MIME content type - - - MIME content encoding - - - Message header field table - - - Non-persistent (1) or persistent (2) - - - The message priority, 0 to 9 - - - The application correlation identifier - - - The destination to reply to - - - Message expiration specification - - - The application message identifier - - - The message timestamp - - - The message type name - - - The creating user id - - - The creating application id - - - Intra-cluster routing identifier - - - - - - - specify quality of service - - 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. - - - - - - prefetch window in octets - - 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. - - - 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. - - - - - prefetch window in messages - - 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. - - - The server MAY send less data in advance than allowed by the - client's specified prefetch windows but it MUST NOT send more. - - - - - apply to entire connection - - By default the QoS settings apply to the current channel only. If - this field is set, they are applied to the entire connection. - - - - - - confirm the requested qos - - 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. - - - - - - - - start a queue consumer - - 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. - - - 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. - - - - - - - The client MUST provide a valid access ticket giving "read" access - rights to the realm for the queue. - - - - - - 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. - - - 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). - - - - - - 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. - - - 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). - - - - - - - - - request exclusive access - - Request exclusive consumer access, meaning only this consumer can - access the queue. - - - 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). - - - - - do not send a reply method - - 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. - - - - - - confirm a new consumer - - 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. - - - - - - Holds the consumer tag specified by the client or provided by - the server. - - - - - - - - - end a queue consumer - - 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. - - - 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. - - - - - - - - do not send a reply method - - 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. - - - - - - confirm a cancelled consumer - - This method confirms that the cancellation was completed. - - - - - - - - - - - publish a message - - 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. - - - - - - The client MUST provide a valid access ticket giving "write" - access rights to the access realm for the exchange. - - - - - - 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. - - - The server MUST accept a blank exchange name to mean the default - exchange. - - - If the exchange was declared as an internal exchange, the server - MUST raise a channel exception with a reply code 403 (access - refused). - - - The exchange MAY refuse basic content in which case it MUST raise - a channel exception with reply code 540 (not implemented). - - - - - Message routing key - - Specifies the routing key for the message. The routing key is - used for routing messages depending on the exchange configuration. - - - - - indicate mandatory routing - - 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. - - - The server SHOULD implement the mandatory flag. - - - - - request immediate delivery - - 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. - - - The server SHOULD implement the immediate flag. - - - - - - return a failed message - - 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. - - - - - - - - - Specifies the name of the exchange that the message was - originally published to. - - - - - Message routing key - - Specifies the routing key name specified when the message was - published. - - - - - - - - - notify the client of a consumer message - - 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. - - - 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. - - - - - - - - - - - - Specifies the name of the exchange that the message was - originally published to. - - - - - Message routing key - - Specifies the routing key name specified when the message was - published. - - - - - - - - - direct access to a queue - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "read" - access rights to the realm for the queue. - - - - - - 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. - - - 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). - - - - - - - - provide client with a message - - 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. - - - - - - - - - - Specifies the name of the exchange that the message was originally - published to. If empty, the message was published to the default - exchange. - - - - - Message routing key - - Specifies the routing key name specified when the message was - published. - - - - - number of messages pending - - 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. - - - - - - - indicate no messages available - - This method tells the client that the queue has no messages - available for the client. - - - - - Cluster id - - For use by cluster applications, should not be used by - client applications. - - - - - - - - acknowledge one or more messages - - 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. - - - - - - acknowledge multiple messages - - 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. - - - 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. - - - - - - - - reject an incoming message - - 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. - - - 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). - - - The server SHOULD interpret this method as meaning that the client - is unable to process the message at this time. - - - 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. - - - - - - - requeue the message - - If this field is zero, the message will be discarded. If this bit - is 1, the server will attempt to requeue the message. - - - 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. - - - - - - redeliver unacknowledged messages - - 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. - - - - - requeue the message - - 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. - - - - The server MUST set the redelivered flag on all messages that are resent. - - - The server MUST raise a channel exception if this is called on a - transacted channel. - - - - - - - - - work with file content - - 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. - - - - 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 - - - - - - - The server MUST make a best-effort to hold file messages on a - reliable storage mechanism. - - - 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. - - - 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. - - - The server MUST support both automatic and explicit acknowledgements - on file content. - - - - - - MIME content type - - - MIME content encoding - - - Message header field table - - - The message priority, 0 to 9 - - - The destination to reply to - - - The application message identifier - - - The message filename - - - The message timestamp - - - Intra-cluster routing identifier - - - - - - - specify quality of service - - 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. - - - - - - prefetch window in octets - - 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. - - - - - prefetch window in messages - - 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. - - - The server MAY send less data in advance than allowed by the - client's specified prefetch windows but it MUST NOT send more. - - - - - apply to entire connection - - By default the QoS settings apply to the current channel only. If - this field is set, they are applied to the entire connection. - - - - - - confirm the requested qos - - 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. - - - - - - - - start a queue consumer - - 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. - - - 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. - - - - - - - The client MUST provide a valid access ticket giving "read" access - rights to the realm for the queue. - - - - - - 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. - - - 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). - - - - - - 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. - - - 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). - - - - - - - - - request exclusive access - - Request exclusive consumer access, meaning only this consumer can - access the queue. - - - 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). - - - - - do not send a reply method - - 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. - - - - - - confirm a new consumer - - This method provides the client with a consumer tag which it MUST - use in methods that work with the consumer. - - - - - - Holds the consumer tag specified by the client or provided by - the server. - - - - - - - - - end a queue consumer - - 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. - - - - - - - - do not send a reply method - - 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. - - - - - - confirm a cancelled consumer - - This method confirms that the cancellation was completed. - - - - - - - - - - - request to start staging - - 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. - - - - - - - staging identifier - - 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.). - - - - - message content size - - 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. - - - The sender MUST accurately fill the content-size field. - Zero-length content is permitted. - - - - - - confirm staging ready - - 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. - - - - - - - already staged amount - - The amount of previously-staged content in octets. For a new - message this will be zero. - - - The sender MUST start sending data from this octet offset in the - message, counting from zero. - - - 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. - - - - - - - - stage message content - - This method stages the message, sending the message content to the - recipient from the octet offset specified in the Open-Ok method. - - - - - - - - - - publish a message - - 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. - - - - - - The client MUST provide a valid access ticket giving "write" - access rights to the access realm for the exchange. - - - - - - 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. - - - The server MUST accept a blank exchange name to mean the default - exchange. - - - 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. - - - The exchange MAY refuse file content in which case it MUST respond - with a reply code 540 (not implemented) and raise a channel - exception. - - - - - Message routing key - - Specifies the routing key for the message. The routing key is - used for routing messages depending on the exchange configuration. - - - - - indicate mandatory routing - - 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. - - - The server SHOULD implement the mandatory flag. - - - - - request immediate delivery - - 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. - - - The server SHOULD implement the immediate flag. - - - - - staging identifier - - 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. - - - - - - return a failed message - - 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. - - - - - - - - - Specifies the name of the exchange that the message was - originally published to. - - - - - Message routing key - - Specifies the routing key name specified when the message was - published. - - - - - - - - - notify the client of a consumer message - - 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. - - - 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. - - - - - - - - - - - - Specifies the name of the exchange that the message was originally - published to. - - - - - Message routing key - - Specifies the routing key name specified when the message was - published. - - - - - staging identifier - - 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. - - - - - - - - - acknowledge one or more messages - - 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. - - - - - - acknowledge multiple messages - - 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. - - - 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. - - - - - - - - - reject an incoming message - - 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. - - - The server SHOULD interpret this method as meaning that the client - is unable to process the message at this time. - - - 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. - - - - - - - requeue the message - - If this field is zero, the message will be discarded. If this bit - is 1, the server will attempt to requeue the message. - - - 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. - - - - - - - - - work with streaming content - - - 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. - - - - stream = C:QOS S:QOS-OK - / C:CONSUME S:CONSUME-OK - / C:CANCEL S:CANCEL-OK - / C:PUBLISH content - / S:RETURN - / S:DELIVER content - - - - - - - The server SHOULD discard stream messages on a priority basis if - the queue size exceeds some configured limit. - - - 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. - - - 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. - - - - - - - MIME content type - - - MIME content encoding - - - Message header field table - - - The message priority, 0 to 9 - - - The message timestamp - - - - - - - specify quality of service - - 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. - - - - - - prefetch window in octets - - 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. - - - - - prefetch window in messages - - 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. - - - - - transfer rate in octets/second - - 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. - - - 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. - - - - - apply to entire connection - - By default the QoS settings apply to the current channel only. If - this field is set, they are applied to the entire connection. - - - - - - confirm the requested qos - - 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. - - - - - - - - start a queue consumer - - 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. - - - 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. - - - 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. - - - - - - - The client MUST provide a valid access ticket giving "read" access - rights to the realm for the queue. - - - - - - 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. - - - 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). - - - - - - 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. - - - 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). - - - - - - - request exclusive access - - Request exclusive consumer access, meaning only this consumer can - access the queue. - - - 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). - - - - - do not send a reply method - - 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. - - - - - - - confirm a new consumer - - This method provides the client with a consumer tag which it may - use in methods that work with the consumer. - - - - - - Holds the consumer tag specified by the client or provided by - the server. - - - - - - - - end a queue consumer - - 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. - - - - - - - - do not send a reply method - - 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. - - - - - - confirm a cancelled consumer - - This method confirms that the cancellation was completed. - - - - - - - - - - - publish a message - - 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. - - - - - - The client MUST provide a valid access ticket giving "write" - access rights to the access realm for the exchange. - - - - - - 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. - - - The server MUST accept a blank exchange name to mean the default - exchange. - - - 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. - - - The exchange MAY refuse stream content in which case it MUST - respond with a reply code 540 (not implemented) and raise a - channel exception. - - - - - Message routing key - - Specifies the routing key for the message. The routing key is - used for routing messages depending on the exchange configuration. - - - - - indicate mandatory routing - - 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. - - - The server SHOULD implement the mandatory flag. - - - - - request immediate delivery - - 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. - - - The server SHOULD implement the immediate flag. - - - - - - return a failed message - - 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. - - - - - - - - - Specifies the name of the exchange that the message was - originally published to. - - - - - Message routing key - - Specifies the routing key name specified when the message was - published. - - - - - - - - - notify the client of a consumer message - - 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. - - - - - - - - - - Specifies the name of the exchange that the message was originally - published to. - - - - - - Specifies the name of the queue that the message came from. Note - that a single channel can start many consumers on different - queues. - - - - - - - - - work with standard transactions - - - 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. - - - 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. - - - tx = C:SELECT S:SELECT-OK - / C:COMMIT S:COMMIT-OK - / C:ROLLBACK S:ROLLBACK-OK - - - - - -select standard transaction mode - - 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. - - - - - -confirm transaction mode - - This method confirms to the client that the channel was successfully - set to use standard transactions. - - - - - -commit the current transaction - - This method commits all messages published and acknowledged in - the current transaction. A new transaction starts immediately - after a commit. - - - - - -confirm a successful commit - - This method confirms to the client that the commit succeeded. - Note that if a commit fails, the server raises a channel exception. - - - - - -abandon the current transaction - - This method abandons all messages published and acknowledged in - the current transaction. A new transaction starts immediately - after a rollback. - - - - - -confirm a successful rollback - - This method confirms to the client that the rollback succeeded. - Note that if an rollback fails, the server raises a channel exception. - - - - - - - work with distributed transactions - - - 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. - - - dtx = C:SELECT S:SELECT-OK - C:START S:START-OK - - - - - -select standard transaction mode - - 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. - - - - - -confirm transaction mode - - This method confirms to the client that the channel was successfully - set to use distributed transactions. - - - - - - start a new distributed transaction - - 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. - - - - - transaction identifier - - The distributed transaction key. This identifies the transaction - so that the AMQP server can coordinate with the distributed - transaction coordinator. - - - - - - confirm the start of a new distributed transaction - - This method confirms to the client that the transaction started. - Note that if a start fails, the server raises a channel exception. - - - - - - - methods for protocol tunneling. - - - The tunnel methods are used to send blocks of binary data - which - can be serialised AMQP methods or other protocol frames - between - AMQP peers. - - - tunnel = C:REQUEST - / S:REQUEST - - - - - Message header field table - - - The identity of the tunnelling proxy - - - The name or type of the message being tunnelled - - - The message durability indicator - - - The message broadcast mode - - - - sends a tunnelled method - - 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. - - - - meta data for the tunnelled block - - This field table holds arbitrary meta-data that the sender needs - to pass to the recipient. - - - - - - - test functional primitives of the implementation - - - 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. - - - 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 - - - - - - test integer handling - - This method tests the peer's capability to correctly marshal integer - data. - - - - - - octet test value - - An octet integer test value. - - - - short test value - - A short integer test value. - - - - long test value - - A long integer test value. - - - - long-long test value - - A long long integer test value. - - - - operation to test - - The client must execute this operation on the provided integer - test fields and return the result. - - - return sum of test values - return lowest of test values - return highest of test values - - - - - report integer test result - - This method reports the result of an Integer method. - - - - - result value - - The result of the tested operation. - - - - - - test string handling - - This method tests the peer's capability to correctly marshal string - data. - - - - - - short string test value - - An short string test value. - - - - long string test value - - A long string test value. - - - - operation to test - - The client must execute this operation on the provided string - test fields and return the result. - - - return concatentation of test strings - return shortest of test strings - return longest of test strings - - - - - report string test result - - This method reports the result of a String method. - - - - - result value - - The result of the tested operation. - - - - - - test field table handling - - This method tests the peer's capability to correctly marshal field - table data. - - - - - - field table of test values - - A field table of test values. - - - - operation to test on integers - - The client must execute this operation on the provided field - table integer values and return the result. - - - return sum of numeric field values - return min of numeric field values - return max of numeric field values - - - - operation to test on strings - - The client must execute this operation on the provided field - table string values and return the result. - - - return concatenation of string field values - return shortest of string field values - return longest of string field values - - - - - report table test result - - This method reports the result of a Table method. - - - - - integer result value - - The result of the tested integer operation. - - - - string result value - - The result of the tested string operation. - - - - - - test content handling - - This method tests the peer's capability to correctly marshal content. - - - - - - - report content test result - - This method reports the result of a Content method. It contains the - content checksum and echoes the original content as provided. - - - - - content hash - - The 32-bit checksum of the content, calculated by adding the - content into a 32-bit accumulator. - - - - - diff --git a/cpp/gentools/xml-src/amqp-0.9.test.xml b/cpp/gentools/xml-src/amqp-0.9.test.xml deleted file mode 100644 index e12e9c787a..0000000000 --- a/cpp/gentools/xml-src/amqp-0.9.test.xml +++ /dev/null @@ -1,4282 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - 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. - - - - - - The client attempted to transfer content larger than the server could accept - at the present time. The client may retry at a later time. - - - - - - An operator intervened to close the connection for some reason. The client - may retry at some later date. - - - - - - The client tried to work with an unknown virtual host. - - - - - - The client attempted to work with a server entity to which it has no - access due to security settings. - - - - - The client attempted to work with a server entity that does not exist. - - - - - The client attempted to work with a server entity to which it has no - access because another client is working with it. - - - - - - The client requested a method that was not allowed because some precondition - failed. - - - - - - The client sent a malformed frame that the server could not decode. This - strongly implies a programming error in the client. - - - - - - The client sent a frame that contained illegal values for one or more - fields. This strongly implies a programming error in the client. - - - - - - 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. - - - - - - The client attempted to work with a channel that had not been correctly - opened. This most likely indicates a fault in the client layer. - - - - - - 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. - - - - - - 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. - - - - - - The client tried to use functionality that is not implemented in the - server. - - - - - - 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. - - - - - - - - - - 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. - - - - - - - - - Identifier for the consumer, valid within the current connection. - - - - - - The server-assigned and channel-specific delivery tag - - - - 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. - - - - - The server MUST NOT use a zero value for delivery tags. Zero is reserved - for client use, meaning "all messages so far received". - - - - - - - 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. - - - - - - - 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. - - - - - - - - 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. - - - - - - If the no-local field is set the server will not send messages to the client that - published them. - - - - - - 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 - [.-_+!=:]. - - - - - - - - - - This string provides a set of peer properties, used for identification, debugging, and - general information. - - - - - - The queue name identifies the queue within the vhost. Queue names may consist of any - mixture of digits, letters, and underscores. - - - - - - - This indicates that the message has been previously delivered to this or - another client. - - - - 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. - - - 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. - - - - - 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. - - - - - - - The reply code. The AMQ reply codes are defined as constants at the start - of this formal specification. - - - - - - - The localised reply text. This text can be logged as an aid to resolving - issues. - - - - - - - - - - - - - - - - - - - - - - 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. - - - - 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 - - - - - - - - - - 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. - - - - - If the server cannot support the protocol specified in the protocol header, - it MUST close the socket connection without sending any response method. - - - The client sends a protocol header containing an invalid protocol name. - The server must respond by closing the connection. - - - - - The server MUST provide a protocol version that is lower than or equal to - that requested by the client in the protocol header. - - - 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. - - - - - If the client cannot handle the protocol version suggested by the server - it MUST close the socket connection. - - - 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. - - - - - - - - - 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. - - - This field should be renamed to "protocol version". - - - - - - 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". - - - This field should be renamed to "protocol revision". - - - - - - - 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. - - - Client connects to server and inspects the server properties. It checks for - the presence of the required fields. - - - - - - - A list of the security mechanisms that the server supports, delimited by spaces. - Currently ASL supports these mechanisms: PLAIN. - - - - - - - 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. - - - - The server MUST support at least the en_US locale. - - - Client connects to server and inspects the locales field. It checks for - the presence of the required locale(s). - - - - - - - - - This method selects a SASL security mechanism. ASL uses SASL (RFC2222) to - negotiate authentication and encryption. - - - - - - - - - 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. - - - - - - - A single security mechanisms selected by the client, which must be one of those - specified by the server. - - - - The client SHOULD authenticate using the highest-level security profile it - can handle from the list provided by the server. - - - - - 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. - - - 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). - - - - - - - - A block of opaque data passed to the security mechanism. The contents of this - data are defined by the SASL security mechanism. - - - - - - - A single message local selected by the client, which must be one of those - specified by the server. - - - - - - - - - - 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. - - - - - - - - Challenge information, a block of opaque binary data passed to the security - mechanism. - - - - - - - This method attempts to authenticate, passing a block of SASL data for the security - mechanism at the server side. - - - - - - - A block of opaque data passed to the security mechanism. The contents of this - data are defined by the SASL security mechanism. - - - - - - - - - - This method proposes a set of connection configuration values to the client. The - client can accept and/or adjust these. - - - - - - - - - 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. - - - - - - 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. - - - - 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. - - - Client connects to server and sends a large properties field, creating a frame - of frame-min-size octets. The server must accept this frame. - - - - - - - - The delay, in seconds, of the connection heartbeat that the server wants. - Zero means the server does not want a heartbeat. - - - - - - - This method sends the client's connection tuning parameters to the server. - Certain fields are negotiated, others provide capability information. - - - - - - - The maximum total number of channels that the client will use per connection. - - - - 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. - - - - - - - - - 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. - - - - 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. - - - - - 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. - - - - - - - The delay, in seconds, of the connection heartbeat that the client wants. Zero - means the client does not want a heartbeat. - - - - - - - - - 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. - - - - - - - - - - - The name of the virtual host to work with. - - - - 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. - - - - - The server SHOULD verify that the client has permission to access the - specified virtual host. - - - - - - - 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. - - - - - - 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. - - - - 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. - - - - - - - - This method signals to the client that the connection is ready for use. - - - - - - - - This method redirects the client to another server, based on the requested virtual - host and/or capabilities. - - - - 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. - - - - - - 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. - - - - - - - - - - - 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. - - - - - After sending this method any received method except the Close-OK method MUST - be discarded. - - - - - - - - - - - - - When the close is provoked by a method exception, this is the class of the - method. - - - - - - When the close is provoked by a method exception, this is the ID of the method. - - - - - - - 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. - - - - A peer that detects a socket closure without having received a Close-Ok - handshake method SHOULD log the error. - - - - - - - - - - - - The channel class provides methods for a client to establish a channel to a - server and for both peers to operate the channel thereafter. - - - - 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 - - - - - - - - - - This method opens a channel to the server. - - - - The client MUST NOT use this method on an alread-opened channel. - - - Client opens a channel and then reopens the same channel. - - - - - - - Configures out-of-band transfers on this channel. The syntax and meaning of this - field will be formally defined at a later date. - - - - - - - - This method signals to the client that the channel is ready for use. - - - - - - - - - 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. - - - - - 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. - - - - - - When sending content frames, a peer SHOULD monitor the channel for incoming - methods and respond to a Channel.Flow as rapidly as possible. - - - - - - 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. - - - - - - 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. - - - - - - - - - - - If 1, the peer starts sending content frames. If 0, the peer stops sending - content frames. - - - - - - - Confirms to the peer that a flow command was received and processed. - - - - - - 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. - - - - - - - - - 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. - - - - - - - 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). - - - - - - - - - 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. - - - - - - After sending this method any received method except the Close-OK method MUST - be discarded. - - - - - - - - - - - - - When the close is provoked by a method exception, this is the class of the - method. - - - - - - When the close is provoked by a method exception, this is the ID of the method. - - - - - - - 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. - - - - A peer that detects a socket closure without having received a Channel.Close-Ok - handshake method SHOULD log the error. - - - - - - - - - - - - - - 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. - - - - access = C:REQUEST S:REQUEST-OK - - - - - - - - - - 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. - - - - - - - - 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. - - - - 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. - - - Client specifies an undefined realm. - - - - - - - Request exclusive access to the realm, meaning that this will be the only - channel that uses the realm's resources. - - - - 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. - - - Client opens two channels and requests exclusive access to the same realm. - - - - - - 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. - - - - - Request message active access to the specified access realm. Active access lets - a client get create and delete resources in the realm. - - - - - Request write access to the specified access realm. Write access lets a client - publish messages to all exchanges in the realm. - - - - - Request read access to the specified access realm. Read access lets a client - consume messages from queues in the realm. - - - - - - - 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. - - - - The client MUST NOT use access tickets except within the same channel as - originally granted. - - - Client opens two channels, requests a ticket on one channel, and then - tries to use that ticket in a seconc channel. - - - - - - - - - - - - Exchanges match and distribute messages across queues. Exchanges can be configured in - the server or created at runtime. - - - - exchange = C:DECLARE S:DECLARE-OK - / C:DELETE S:DELETE-OK - - - - - - - - The server MUST implement these standard exchange types: fanout, direct. - - - Client attempts to declare an exchange with each of these standard types. - - - - - The server SHOULD implement these standard exchange types: topic, headers. - - - Client attempts to declare an exchange with each of these standard types. - - - - - 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. - - - 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). - - - - - The server MUST predeclare a direct exchange to act as the default exchange - for content Publish methods and for default queue bindings. - - - 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. - - - - - 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. - - - - - The server MAY implement other exchange types as wanted. - - - - - - - - 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. - - - - The server SHOULD support a minimum of 16 exchanges per virtual host and - ideally, impose no limit except as defined by available resources. - - - 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. - - - - - - - - - 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. - - - - 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. - - - Client creates access ticket with wrong access rights and attempts to use - in this method. - - - - - - - - Exchange names starting with "amq." are reserved for predeclared and - standardised exchanges. The client MUST NOT attempt to create an exchange - starting with "amq.". - - - TODO. - - - - - - - - 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. - - - - 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. - - - TODO. - - - - - The client MUST NOT attempt to create an exchange with a type that the - server does not support. - - - TODO. - - - - - - - - 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. - - - - If set, and the exchange does not already exist, the server MUST raise a - channel exception with reply code 404 (not found). - - - TODO. - - - - - - - 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. - - - - The server MUST support both durable and transient exchanges. - - - TODO. - - - - - The server MUST ignore the durable field if the exchange already exists. - - - TODO. - - - - - - - - If set, the exchange is deleted when all queues have finished using it. - - - - The server MUST ignore the auto-delete field if the exchange already - exists. - - - TODO. - - - - - - - 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. - - - - - - 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. - - - - - - 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. - - - - - - - This method confirms a Declare method and confirms the name of the exchange, - essential for automatically-named exchanges. - - - - - - - - - This method deletes an exchange. When an exchange is deleted all queue bindings on - the exchange are cancelled. - - - - - - - - - The client MUST provide a valid access ticket giving "active" access - rights to the exchange's access realm. - - - Client creates access ticket with wrong access rights and attempts to use - in this method. - - - - - - - - The client MUST NOT attempt to delete an exchange that does not exist. - - - - - - - - - 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. - - - - - - 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. - - - - - - This method confirms the deletion of an exchange. - - - - - - - - - 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. - - - - queue = C:DECLARE S:DECLARE-OK - / C:BIND S:BIND-OK - / C:PURGE S:PURGE-OK - / C:DELETE S:DELETE-OK - - - - - - - - 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. - - - 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. - - - - - - - - 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. - - - - - The server MUST create a default binding for a newly-created queue to the - default exchange, which is an exchange of type 'direct'. - - - 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. - - - - - - - The server SHOULD support a minimum of 256 queues per virtual host and ideally, - impose no limit except as defined by available resources. - - - Client attempts to create as many queues as it can until the server reports - an error. The resulting count must at least be 256. - - - - - - - - - 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. - - - - The client MUST provide a valid access ticket giving "active" access to - the realm in which the queue exists or will be created. - - - Client creates access ticket with wrong access rights and attempts to use - in this method. - - - - - - - - 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. - - - Client attempts to create several queues with an empty name. The client then - verifies that the server-assigned names are unique and different. - - - - - 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. - - - A client attempts to create a queue with a name starting with "amq." and with - the passive option set to zero. - - - - - - - - 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. - - - - 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. - - - 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. - - - - - - - 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. - - - - The server MUST recreate the durable queue after a restart. - - - - 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. - - - - - The server MUST support both durable and transient queues. - - A client creates two named queues, one durable and one transient. - - - - - The server MUST ignore the durable field if the queue already exists. - - 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. - - - - - - - - Exclusive queues may only be consumed from by the current connection. Setting - the 'exclusive' flag always implies 'auto-delete'. - - - - - - The server MUST support both exclusive (private) and non-exclusive (shared) - queues. - - - A client creates two named queues, one exclusive and one non-exclusive. - - - - - - - The client MAY NOT attempt to declare any existing and exclusive queue - on multiple connections. - - - A client declares an exclusive named queue. A second client on a different - connection attempts to declare a queue of the same name. - - - - - - - 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. - - - - - - The server MUST ignore the auto-delete field if the queue already exists. - - - 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. - - - - - - - - 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. - - - - - - 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. - - - - - - - This method confirms a Declare method and confirms the name of the queue, essential - for automatically-named queues. - - - - - - - Reports the name of the queue. If the server generated a queue name, this field - contains that name. - - - - - - - Reports the number of messages in the queue, which will be zero for - newly-created queues. - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - A client binds a named queue to an exchange. The client then repeats the bind - (with identical arguments). - - - - - - - If a bind fails, the server MUST raise a connection exception. - - TODO - - - - - - - The server MUST NOT allow a durable queue to bind to a transient exchange. - - - 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. - - - - - - - Bindings for durable queues are automatically durable and the server SHOULD - restore such bindings after a server restart. - - - 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. - - - - - - - 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). - - - A client attempts to bind a named queue to an internal exchange. - - - - - - - The server SHOULD support at least 4 bindings per queue, and ideally, impose no - limit except as defined by available resources. - - - A client creates a named queue and attempts to bind it to 4 different non-internal - exchanges. - - - - - - - - - - The client provides a valid access ticket giving "active" access rights to the - queue's access realm. - - - - - - 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. - - - - - A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e. - empty queue name) to an exchange. - - - A client attempts to bind with an unnamed (empty) queue name to an exchange. - - - - - - - A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously - declared) to an exchange. - - - A client attempts to bind an undeclared queue name to an exchange. - - - - - - - - - A client MUST NOT be allowed to bind a queue to a non-existent exchange. - - - A client attempts to bind an named queue to a undeclared exchange. - - - - - - - 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. - - - - - - 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. - - - - - - A set of arguments for the binding. The syntax and semantics of these arguments - depends on the exchange class. - - - - - - This method confirms that the bind was successful. - - - - - - - - - This method removes all messages from a queue. It does not cancel consumers. Purged - messages are deleted without any formal "undo" mechanism. - - - - - A call to purge MUST result in an empty queue. - - - - - - On transacted channels the server MUST not purge messages that have already been - sent to a client but not yet acknowledged. - - - - - - - - - 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. - - - - - - - - - The access ticket must be for the access realm that holds the queue. - - - - 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. - - - - - - - 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. - - - - - 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). - - - - - - - - - The queue MUST exist. Attempting to purge a non-existing queue MUST cause a - channel exception. - - - - - - - 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. - - - - - - This method confirms the purge of a queue. - - - - - Reports the number of messages purged. - - - - - - - - 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. - - - - - - - - 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. - - - - - - - - - - The client provides a valid access ticket giving "active" access rights to the - queue's access realm. - - - - - - 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. - - - - - 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). - - - - - - - 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). - - - - - - - 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. - - - - - The server MUST respect the if-unused flag when deleting a queue. - - - - - - If set, the server will only delete the queue if it has no messages. - - - - If the queue is not empty the server MUST raise a channel exception with - reply code 406 (precondition failed). - - - - - - - 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. - - - - - - This method confirms the deletion of a queue. - - - - - Reports the number of messages purged. - - - - - - - - - The Basic class provides methods that support an industry-standard messaging model. - - - - 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 - - - - - - - - - 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. - - - 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. - - - - - - - The server MUST NOT discard a persistent basic message in case of a queue - overflow. - - - Create a queue overflow situation with persistent messages and verify that - messages do not get lost (presumably the server will write them to disk). - - - - - - The server MAY use the Channel.Flow method to slow or stop a basic message - publisher when necessary. - - - Create a queue overflow situation with non-persistent messages and verify - whether the server responds with Channel.Flow or not. Repeat with persistent - messages. - - - - - - - The server MAY overflow non-persistent basic messages to persistent - storage. - - - - - - - The server MAY discard or dead-letter non-persistent basic messages on a - priority basis if the queue size exceeds some configured limit. - - - - - - - - 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. - - - 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. - - - - - - The server MAY implement up to 10 priority levels. - - - 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. - - - - - - - The server MUST deliver messages of the same priority in order irrespective of - their individual persistence. - - - 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. - - - - - - - The server MUST support automatic acknowledgements on Basic content, i.e. - consumers with the no-ack field set to FALSE. - - - 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. - - - - - - The server MUST support explicit acknowledgements on Basic content, i.e. - consumers with the no-ack field set to TRUE. - - - 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. - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - - - 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. - - - - - 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. - - - Define a QoS prefetch-size limit and send a single message that exceeds - that limit. Verify that the message arrives correctly. - - - - - - - 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. - - - - - The server may send less data in advance than allowed by the client's - specified prefetch windows but it MUST NOT send more. - - - 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. - - - - - - - By default the QoS settings apply to the current channel only. If this field is - set, they are applied to the entire connection. - - - - - - - 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. - - - - - - - - - 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. - - - - - - The server SHOULD support at least 16 consumers per queue, and ideally, impose - no limit except as defined by available resources. - - - 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. - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - Attempt to create a consumer with an invalid (non-zero) access ticket. - - - - - - - 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. - - - - If the queue name is empty the client MUST have previously declared a - queue using this channel. - - - Attempt to create a consumer with an empty queue name and no previously - declared queue on the channel. - - - - - - - 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. - - - - The client MUST NOT specify a tag that refers to an existing consumer. - - - Attempt to create two consumers with the same non-empty tag. - - - - - 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. - - - 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). - - - - - - - - - - - Request exclusive consumer access, meaning only this consumer can access the - queue. - - - - - The client MAY NOT gain exclusive access to a queue that already has - active consumers. - - - 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. - - - - - - - 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. - - - - - - - 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. - - - - - Holds the consumer tag specified by the client or provided by the server. - - - - - - - - - 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. - - - - - If the queue does not exist the server MUST ignore the cancel method, so - long as the consumer tag is valid for that channel. - - - TODO. - - - - - - - - - - - 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. - - - - - - - This method confirms that the cancellation was completed. - - - - - - - - - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "write" access rights - to the access realm for the exchange. - - - TODO. - - - - - - - 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. - - - - - - The server MUST accept a blank exchange name to mean the default exchange. - - - TODO. - - - - - - - If the exchange was declared as an internal exchange, the server MUST raise - a channel exception with a reply code 403 (access refused). - - - TODO. - - - - - - - The exchange MAY refuse basic content in which case it MUST raise a channel - exception with reply code 540 (not implemented). - - - TODO. - - - - - - - Specifies the routing key for the message. The routing key is used for routing - messages depending on the exchange configuration. - - - - - - 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. - - - - - The server SHOULD implement the mandatory flag. - - - TODO. - - - - - - - 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. - - - - - The server SHOULD implement the immediate flag. - - - TODO. - - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - - 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. - - - - - - - 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. - - - TODO. - - - - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - 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. - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - TODO. - - - - - - - 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. - - - - 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). - - - TODO. - - - - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - If empty, the message was published to the default exchange. - - - - - Specifies the routing key name specified when the message was published. - - - - - 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. - - - - - - - This method tells the client that the queue has no messages available for the - client. - - - - - - - - For use by cluster applications, should not be used by client applications. - - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - TODO. - - - - - - - - - - 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. - - - - - - 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). - - - - - - - The server SHOULD interpret this method as meaning that the client is unable to - process the message at this time. - - - TODO. - - - - - - - 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. - - - TODO. - - - - - - - - - - If this field is zero, the message will be discarded. If this bit is 1, the - server will attempt to requeue the message. - - - - - - - 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. - - - TODO. - - - - - - - - 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. - - - - - The server MUST set the redelivered flag on all messages that are resent. - - - TODO. - - - - - - The server MUST raise a channel exception if this is called on a transacted - channel. - - - TODO. - - - - - - - - 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. - - - - - - - - - - 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. - - - - 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 - - - - - - - - The server MUST make a best-effort to hold file messages on a reliable storage - mechanism. - - - - - - - - - - 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. - - - - - - - - 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. - - - - - - The server MUST support both automatic and explicit acknowledgements on file - content. - - - - - - - - - - - - - - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - - - - The server MAY send less data in advance than allowed by the client's - specified prefetch windows but it MUST NOT send more. - - - - - - - By default the QoS settings apply to the current channel only. If this field is - set, they are applied to the entire connection. - - - - - - - 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. - - - - - - - - - - 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. - - - - - 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. - - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - - - - - 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. - - - - - 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). - - - - - - - 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. - - - - - - 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). - - - - - - - - - - - Request exclusive consumer access, meaning only this consumer can access the - queue. - - - - - - 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). - - - - - - - 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. - - - - - - - This method provides the client with a consumer tag which it MUST use in methods - that work with the consumer. - - - - - - Holds the consumer tag specified by the client or provided by the server. - - - - - - - - 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. - - - - - - - - - - - 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. - - - - - - This method confirms that the cancellation was completed. - - - - - - - - - - - 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. - - - - - - - - - - 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.). - - - - - - 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. - - - - - The sender MUST accurately fill the content-size field. Zero-length content - is permitted. - - - - - - - - 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. - - - - - - - - - - The amount of previously-staged content in octets. For a new message this will - be zero. - - - - - The sender MUST start sending data from this octet offset in the message, - counting from zero. - - - - - - - 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. - - - - - - - - - - This method stages the message, sending the message content to the recipient from - the octet offset specified in the Open-Ok method. - - - - - - - - - - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "write" access rights - to the access realm for the exchange. - - - - - - - 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. - - - - - The server MUST accept a blank exchange name to mean the default exchange. - - - - - - 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. - - - - - - - - The exchange MAY refuse file content in which case it MUST respond with a - reply code 540 (not implemented) and raise a channel exception. - - - - - - - Specifies the routing key for the message. The routing key is used for routing - messages depending on the exchange configuration. - - - - - - 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. - - - - - The server SHOULD implement the mandatory flag. - - - - - - 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. - - - - - The server SHOULD implement the immediate flag. - - - - - - 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. - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - 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. - - - - - - 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. - - - - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - 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. - - - - - - - - - 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. - - - - - - - - - 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. - - - - - 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. - - - - - - - - - - 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. - - - - - The server SHOULD interpret this method as meaning that the client is unable to - process the message at this time. - - - - - - - - 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. - - - - - - - - - - If this field is zero, the message will be discarded. If this bit is 1, the - server will attempt to requeue the message. - - - - - - 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. - - - - - - - - - - - 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. - - - - stream = C:QOS S:QOS-OK - / C:CONSUME S:CONSUME-OK - / C:CANCEL S:CANCEL-OK - / C:PUBLISH content - / S:RETURN - / S:DELIVER content - - - - - - - - The server SHOULD discard stream messages on a priority basis if the queue size - exceeds some configured limit. - - - - - - - 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. - - - - - - 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. - - - - - - - - - - - - - - - - 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. - - - - - - - - - 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. - - - - - - 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. - - - - - - 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. - - - - - - 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. - - - - - - - By default the QoS settings apply to the current channel only. If this field is - set, they are applied to the entire connection. - - - - - - - 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. - - - - - - - - - - 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. - - - - - 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. - - - - - - 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. - - - - - - - - - - The client MUST provide a valid access ticket giving "read" access rights to - the realm for the queue. - - - - - - - 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. - - - - - 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). - - - - - - - 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. - - - - - - 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). - - - - - - - - - Request exclusive consumer access, meaning only this consumer can access the - queue. - - - - - - - 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). - - - - - - - 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. - - - - - - - This method provides the client with a consumer tag which it may use in methods that - work with the consumer. - - - - - - Holds the consumer tag specified by the client or provided by the server. - - - - - - - - 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. - - - - - - - - - - - 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. - - - - - - This method confirms that the cancellation was completed. - - - - - - - - - - - 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. - - - - - - - - The client MUST provide a valid access ticket giving "write" access rights - to the access realm for the exchange. - - - - - - - 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. - - - - - The server MUST accept a blank exchange name to mean the default exchange. - - - - - - 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. - - - - - - The exchange MAY refuse stream content in which case it MUST respond with a - reply code 540 (not implemented) and raise a channel exception. - - - - - - - Specifies the routing key for the message. The routing key is used for routing - messages depending on the exchange configuration. - - - - - - 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. - - - - - The server SHOULD implement the mandatory flag. - - - - - - 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. - - - - - The server SHOULD implement the immediate flag. - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - Specifies the routing key name specified when the message was published. - - - - - - - - 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. - - - - - - - - - - - Specifies the name of the exchange that the message was originally published to. - - - - - - Specifies the name of the queue that the message came from. Note that a single - channel can start many consumers on different queues. - - - - - - - - - - - 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. - - - - - - - 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. - - - - - tx = C:SELECT S:SELECT-OK - / C:COMMIT S:COMMIT-OK - / C:ROLLBACK S:ROLLBACK-OK - - - - - - - - - - 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. - - - - - - - - This method confirms to the client that the channel was successfully set to use - standard transactions. - - - - - - - - - This method commits all messages published and acknowledged in the current - transaction. A new transaction starts immediately after a commit. - - - - - - - - This method confirms to the client that the commit succeeded. Note that if a commit - fails, the server raises a channel exception. - - - - - - - - - This method abandons all messages published and acknowledged in the current - transaction. A new transaction starts immediately after a rollback. - - - - - - - - This method confirms to the client that the rollback succeeded. Note that if an - rollback fails, the server raises a channel exception. - - - - - - - - - - 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. - - - - dtx = C:SELECT S:SELECT-OK - C:START S:START-OK - - - - - - - - - - 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. - - - - - - - - This method confirms to the client that the channel was successfully set to use - distributed transactions. - - - - - - - - - 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. - - - - - - The distributed transaction key. This identifies the transaction so that the - AMQP server can coordinate with the distributed transaction coordinator. - - - - - - - - This method confirms to the client that the transaction started. Note that if a - start fails, the server raises a channel exception. - - - - - - - - - - The tunnel methods are used to send blocks of binary data - which can be serialised AMQP - methods or other protocol frames - between AMQP peers. - - - - tunnel = C:REQUEST - / S:REQUEST - - - - - - - - - - - - - - - - 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. - - - - - This field table holds arbitrary meta-data that the sender needs to - pass to the recipient. - - - - - diff --git a/cpp/gentools/xml-src/cluster-0.9.test.xml b/cpp/gentools/xml-src/cluster-0.9.test.xml deleted file mode 100644 index 142e6c9380..0000000000 --- a/cpp/gentools/xml-src/cluster-0.9.test.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - An extension that allows brokers to communicate in order to - provide a clustered service to clients. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cpp/rubygen/amqpgen.rb b/cpp/rubygen/amqpgen.rb index 7d635c99c2..044a2497e0 100755 --- a/cpp/rubygen/amqpgen.rb +++ b/cpp/rubygen/amqpgen.rb @@ -60,8 +60,7 @@ class AmqpField < AmqpElement # Get AMQP type for a domain name. def domain_type(name) - domain=elements["/amqp/domain[@name='#{name}']"] - (domain and domain.attributes["type"] or name) + @cache_domain_type ||= domain_type_impl(name) end # Get the AMQP type of this field. @@ -70,6 +69,22 @@ class AmqpField < AmqpElement dt=domain_type d if d (dt or attributes["type"]) end + + # determine whether this type is defined as a struct in the spec + def defined_as_struct() + @cache_defined_as_struct ||= defined_as_struct_impl() + end + +private + def domain_type_impl(name) + domain=elements["/amqp/domain[@name='#{name}']"] + (domain and domain.attributes["type"] or name) + end + + def defined_as_struct_impl() + domain_name = attributes["domain"] + elements["/amqp/domain[@name='#{domain_name}']/struct"] + end end # AMQP method element @@ -98,6 +113,18 @@ class AmqpMethod < AmqpElement } end + def has_result?() + @cache_has_result ||= elements["result/struct"] + end + + def result_struct() + @cache_result_struct ||= has_result? ? AmqpStruct.new(elements["result/struct"], self) : nil + end + + def is_server_method?() + @cache_is_server_method ||= elements["chassis[@name='server']"] + end + def request?() responds_to().empty?; end def response?() not request?; end end @@ -116,7 +143,25 @@ class AmqpClass < AmqpElement def amqp_methods_on(chassis) @cache_amqp_methods_on ||= { } @cache_amqp_methods_on[chassis] ||= elements.collect("method/chassis[@name='#{chassis}']/..") { |m| AmqpMethod.new(m,self) }.sort_by_name + end end + + +# AMQP struct element. +class AmqpStruct < AmqpElement + def initialize(xml,amqp) super; end + + def type() attributes["type"]; end + + def size() attributes["size"]; end + + def result?() parent.name == "result"; end + + def domain?() parent.name == "domain"; end + + def fields() + @cache_fields ||= elements.collect("field") { |f| AmqpField.new(f,self); } + end end # AMQP root element. @@ -152,9 +197,23 @@ class AmqpRoot < AmqpElement @cache_amqp_classes ||= elements.collect("class") { |c| AmqpClass.new(c,self) }.sort_by_name end + + def amqp_structs() + @cache_amqp_structs ||= amqp_result_structs + amqp_domain_structs + end + + def amqp_domain_structs() + @cache_amqp_domain_structs ||= elements.collect("domain/struct") { |s| AmqpStruct.new(s, self) } + end + + def amqp_result_structs() + @cache_amqp_result_structs ||= amqp_methods.collect { |m| m.result_struct }.compact + end # Return all methods on all classes. - def amqp_methods() amqp_classes.collect { |c| c.amqp_methods }.flatten; end + def amqp_methods() + @cache_amqp_methods ||= amqp_classes.collect { |c| c.amqp_methods }.flatten; + end # Return all methods on chassis for all classes. def amqp_methods_on(chassis) diff --git a/cpp/rubygen/cppgen.rb b/cpp/rubygen/cppgen.rb index a3314c7e11..109005e743 100755 --- a/cpp/rubygen/cppgen.rb +++ b/cpp/rubygen/cppgen.rb @@ -62,9 +62,11 @@ end # Additional methods for AmqpField. class AmqpField def cppname() @cache_cppname ||= name.lcaps.cppsafe; end - def cpptype() @cache_cpptype ||= amqp_root.param_type(field_type); end + def cpptype() @cache_cpptype ||= defined_as_struct ? "const " + field_type.caps + "&" : amqp_root.param_type(field_type); end + def cpp_member_type() @cache_cpp_member_type ||= defined_as_struct ? field_type.caps : amqp_root.member_type(field_type); end def cppret_type() @cache_cpptype ||= amqp_root.return_type(field_type); end def type_name () @type_name ||= cpptype+" "+cppname; end + def bit?() field_type == "bit" end end # Additional methods for AmqpMethod @@ -82,6 +84,32 @@ class AmqpClass end end +class AmqpStruct + def cppname() + @cache_cppname ||= cppname_impl() + end + +private + + def cppname_impl() + #The name of the struct comes from the context it appears in: + #structs defined in a domain get their name from the domain + #element, structs defined in a result element get their name by + #appending 'Result' to the enclosing method name. + if (domain?) + parent.attributes["name"].caps + else + if (result?) + method = parent.parent + method.parent.attributes["name"].caps + method.attributes["name"].caps + "Result" + else + raise "Bad struct context: expected struct to be child of or " + end + end + + end +end + # Additional methos for AmqpRoot class AmqpRoot # FIXME aconway 2007-06-20: fix u_int types, should be uint @@ -97,6 +125,7 @@ class AmqpRoot "table"=>["FieldTable", "const FieldTable&", "const FieldTable&"], "content"=>["Content", "const Content&", "const Content&"], "rfc1982-long-set"=>["SequenceNumberSet", "const SequenceNumberSet&", "const SequenceNumberSet&"], + "long-struct"=>["string", "const string&"], "uuid"=>["string", "const string&"] # FIXME should be: ["Uuid", "const Uuid&", "const Uuid&"] } diff --git a/cpp/rubygen/generate b/cpp/rubygen/generate index 14b273b688..52313186ed 100755 --- a/cpp/rubygen/generate +++ b/cpp/rubygen/generate @@ -38,6 +38,10 @@ if makefile generator_files=Dir["**/*.rb"] << File.basename(__FILE__) Dir.chdir dir rgen_generator=generator_files.map{ |f| "$(rgen_dir)/#{f}" } + rgen_srcs=GenFiles.get.map{ |f| "#{Outdir}/#{f}" } + rgen_client_cpp = rgen_srcs.select { |f| f =~ /qpid\/client\/.+\.cpp$/ } + rgen_common_cpp = rgen_srcs.select { |f| f =~ /qpid\/framing\/.+\.cpp$/ } + rgen_h = rgen_srcs.select { |f| f =~ /.+\.h$/ } File.open(makefile, 'w') { |out| out << < -#include "qpid/framing/ProtocolVersion.h" - -namespace qpid { -namespace framing { - -class #{@classname} { - - public: - virtual ~#{@classname}() {} - - virtual ProtocolVersion getVersion() const = 0; - - // Include framing constant declarations - #include "AMQP_Constants.h" - - // Inner classes -EOS - indent { @amqp.amqp_classes.each { |c| handler_class(c) } } - gen < " - puts "Note: passing '-' as the output directory lists generated files." - exit 1 -end - -require 'amqpgen' -Amqp=AmqpRoot.new(*ARGV[1,ARGV.size]) - -require 'Proxy.rb' -require 'Operations.rb' - - diff --git a/cpp/rubygen/templates/InvocationVisitor.rb b/cpp/rubygen/templates/InvocationVisitor.rb new file mode 100644 index 0000000000..f3ac03ece2 --- /dev/null +++ b/cpp/rubygen/templates/InvocationVisitor.rb @@ -0,0 +1,105 @@ +#!/usr/bin/env ruby +$: << ".." # Include .. in load path +require 'cppgen' + +class InvocationVisitor < CppGen + + def initialize(outdir, amqp) + super(outdir, amqp) + @namespace="qpid::framing" + @classname="InvocationVisitor" + @filename="qpid/framing/InvocationVisitor" + end + + def invocation_args(m) + if (m.amqp_parent.name == "message" && (m.name == "transfer" || m.name == "append")) + "body" + else + m.param_names.collect {|p| "body.get" + p.caps + "()" }.join(",\n") + end + end + + def null_visit(m) + genl "void InvocationVisitor::visit(const #{m.body_name}&){}" + end + + def define_visit(m) + if (m.fields.size > 0) + body = "body" + else + body = "/*body*/" + end + gen <(invocable); + } else { + ptr = ops->get#{m.amqp_parent.cppname}Handler(); + } + + if (ptr) { +EOS + if (m.has_result?) + indent(2) { genl "encode<#{m.result_struct.cppname.caps}>(ptr->#{m.cppname}(#{invocation_args(m)}), result);" } + else + indent(2) { genl "ptr->#{m.cppname}(#{invocation_args(m)});" } + end + + gen < +#include "qpid/framing/ProtocolVersion.h" +#include "qpid/framing/amqp_structs.h" + +namespace qpid { +namespace framing { + +class AMQMethodBody; + +class Invocable +{ +protected: + Invocable() {} + virtual ~Invocable() {} +}; + +class #{@classname} { + + public: + virtual ~#{@classname}() {} + + virtual ProtocolVersion getVersion() const = 0; + + // Include framing constant declarations - why? + //#include "qpid/framing/AMQP_Constants.h" + + // Inner classes +EOS + indent { @amqp.amqp_classes.each { |c| handler_class(c) } } + gen <"Octet", + "short"=>"Short", + "long"=>"Long", + "longlong"=>"LongLong", + "longstr"=>"LongString", + "shortstr"=>"ShortString", + "timestamp"=>"LongLong", + "uuid"=>"ShortString",#FIXME + "table"=>"FieldTable", + "content"=>"Content", + "long-struct"=>"LongString" + } + SizeMap={ + "octet"=>"1", + "short"=>"2", + "long"=>"4", + "longlong"=>"8", + "timestamp"=>"8" + } + + ValueTypes=["octet", "short", "long", "longlong", "timestamp"] + + def printable_form(f) + if (f.cpptype == "u_int8_t") + return "(int) " + f.cppname + else + return f.cppname + end + end + + def generate_encode(f, combined) + if (f.field_type == "bit") + genl "uint8_t #{f.cppname}_bits = #{f.cppname};" + count = 0 + combined.each { |c| genl "#{f.cppname}_bits |= #{c.cppname} << #{count += 1};" } + genl "buffer.putOctet(#{f.cppname}_bits);" + else + encoded = EncodingMap[f.field_type] + if (encoded) + genl "buffer.put#{encoded}(#{f.cppname});" + else + genl "#{f.cppname}.encode(buffer);" + end + end + end + + def generate_decode(f, combined) + if (f.field_type == "bit") + genl "uint8_t #{f.cppname}_bits = buffer.getOctet();" + genl "#{f.cppname} = 1 & #{f.cppname}_bits;" + count = 0 + combined.each { |c| genl "#{c.cppname} = (1 << #{count += 1}) & #{f.cppname}_bits;" } + else + encoded = EncodingMap[f.field_type] + if (encoded) + if (ValueTypes.include?(f.field_type)) + genl "#{f.cppname} = buffer.get#{encoded}();" + else + genl "buffer.get#{encoded}(#{f.cppname});" + end + else + genl "#{f.cppname}.decode(buffer);" + end + end + end + + def generate_size(f, combined) + if (f.field_type == "bit") + names = ([f] + combined).collect {|g| g.cppname} + genl "+ 1 //#{names.join(", ")}" + else + size = SizeMap[f.field_type] + if (size) + genl "+ #{size} //#{f.cppname}" + elsif (f.cpp_member_type == "SequenceNumberSet") + genl "+ #{f.cppname}.encodedSize()" + else + encoded = EncodingMap[f.field_type] + gen "+ 4 " if encoded == "LongString" + gen "+ 1 " if encoded == "ShortString" + genl "+ #{f.cppname}.size()" + end + end + end + + def process_fields(s) + last = nil + count = 0 + bits = [] + s.fields.each { + |f| if (last and last.bit? and f.bit? and count < 7) + count += 1 + bits << f + else + if (last and last.bit?) + yield last, bits + count = 0 + bits = [] + end + if (not f.bit?) + yield f + end + last = f + end + } + if (last and last.bit?) + yield last, bits + end + end + + def methodbody_extra_defs(s) + gen <#{s.cppname} + ( +EOS + if (s.amqp_parent.name == "message" && (s.name == "transfer" || s.name == "append")) + indent(4) { genl "*this" } + else + indent(4) { genl s.param_names.join(",\n") } + end + + genl <(target); + if (ptr) { + ptr->#{s.cppname}( +EOS + if (s.amqp_parent.name == "message" && (s.name == "transfer" || s.name == "append")) + indent(5) { genl "*this" } + else + indent(5) { genl s.param_names.join(",\n") } + end + + gen < 0) + genl "#{name}(" + if (s.kind_of? AmqpMethod) + indent {gen "ProtocolVersion, "} + end + indent { gen s.fields.collect { |f| "#{f.cpptype} _#{f.cppname}" }.join(",\n") } + gen ")" + genl ": " if s.fields.size > 0 + indent { gen s.fields.collect { |f| " #{f.cppname}(_#{f.cppname})" }.join(",\n") } + genl " {}" + end + if (s.kind_of? AmqpMethod) + genl "#{name}(ProtocolVersion=ProtocolVersion()) {}" + end + end + + def define_accessors(f) + genl "void set#{f.name.caps}(#{f.cpptype} _#{f.cppname}) { #{f.cppname} = _#{f.cppname}; }" + genl "#{f.cpptype} get#{f.name.caps}() const { return #{f.cppname}; }" + end + + def define_struct(s) + classname = s.cppname + inheritance = "" + if (s.kind_of? AmqpMethod) + classname = s.body_name + inheritance = ": public AMQMethodBody" + end + + h_file("qpid/framing/#{classname}.h") { + if (s.kind_of? AmqpMethod) + gen < +#include "qpid/framing/amqp_types_full.h" + +namespace qpid { +namespace framing { + +class #{classname} #{inheritance} { +EOS + indent { s.fields.each { |f| genl "#{f.cpp_member_type} #{f.cppname};" } } + genl "public:" + if (s.kind_of? AmqpMethod) + indent { genl "static const ClassId CLASS_ID = #{s.amqp_parent.index};" } + indent { genl "static const MethodId METHOD_ID = #{s.index};" } + end + + if (s.kind_of? AmqpStruct) + if (s.type) + if (s.result?) + #as result structs have types that are only unique to the + #class, they have a class dependent qualifier added to them + #(this is inline with current python code but a formal + #solution is expected from the WG + indent { genl "static const uint16_t TYPE = #{s.type} + #{s.amqp_parent.amqp_parent.index} * 256;" } + else + indent { genl "static const uint16_t TYPE = #{s.type};" } + end + end + end + + indent { + define_constructor(classname, s) + genl "" + s.fields.each { |f| define_accessors(f) } + } + if (s.kind_of? AmqpMethod) + methodbody_extra_defs(s) + end + if (s.kind_of? AmqpStruct) + indent {genl "friend std::ostream& operator<<(std::ostream&, const #{classname}&);" } + end + + gen < 0) + buffer = "buffer" + else + buffer = "/*buffer*/" + end + gen <getType(), exchange->isDurable(), false, exchange->getArgs()); + return ExchangeQueryResult(exchange->getType(), exchange->isDurable(), false, exchange->getArgs()); } catch (const ChannelException& e) { - client.queryOk("", false, true, FieldTable()); + return ExchangeQueryResult("", false, true, FieldTable()); } } -void BrokerAdapter::BindingHandlerImpl::query(u_int16_t /*ticket*/, +BindingQueryResult BrokerAdapter::BindingHandlerImpl::query(u_int16_t /*ticket*/, const std::string& exchangeName, const std::string& queueName, const std::string& key, @@ -164,24 +164,40 @@ void BrokerAdapter::BindingHandlerImpl::query(u_int16_t /*ticket*/, } if (!exchange) { - client.queryOk(true, false, false, false, false); + return BindingQueryResult(true, false, false, false, false); } else if (!queueName.empty() && !queue) { - client.queryOk(false, true, false, false, false); + return BindingQueryResult(false, true, false, false, false); } else if (exchange->isBound(queue, key.empty() ? 0 : &key, args.count() > 0 ? &args : &args)) { - client.queryOk(false, false, false, false, false); + return BindingQueryResult(false, false, false, false, false); } else { //need to test each specified option individually bool queueMatched = queueName.empty() || exchange->isBound(queue, 0, 0); bool keyMatched = key.empty() || exchange->isBound(Queue::shared_ptr(), &key, 0); bool argsMatched = args.count() == 0 || exchange->isBound(Queue::shared_ptr(), 0, &args); - client.queryOk(false, false, !queueMatched, !keyMatched, !argsMatched); + return BindingQueryResult(false, false, !queueMatched, !keyMatched, !argsMatched); } } +QueueQueryResult BrokerAdapter::QueueHandlerImpl::query(const string& name) +{ + Queue::shared_ptr queue = getQueue(name); + Exchange::shared_ptr alternateExchange = queue->getAlternateExchange(); + + return QueueQueryResult(queue->getName(), + alternateExchange ? alternateExchange->getName() : "", + queue->isDurable(), + queue->hasExclusiveOwner(), + queue->isAutoDelete(), + queue->getSettings(), + queue->getMessageCount(), + queue->getConsumerCount()); + +} + void BrokerAdapter::QueueHandlerImpl::declare(uint16_t /*ticket*/, const string& name, const string& alternateExchange, bool passive, bool durable, bool exclusive, - bool autoDelete, bool nowait, const qpid::framing::FieldTable& arguments){ + bool autoDelete, const qpid::framing::FieldTable& arguments){ Exchange::shared_ptr alternate; if (!alternateExchange.empty()) { alternate = broker.getExchanges().get(alternateExchange); @@ -223,11 +239,6 @@ void BrokerAdapter::QueueHandlerImpl::declare(uint16_t /*ticket*/, const string& 405, format("Cannot grant exclusive access to queue '%s'") % queue->getName()); - if (!nowait) { - string queueName = queue->getName(); - client.declareOk( - queueName, queue->getMessageCount(), queue->getConsumerCount()); - } } void BrokerAdapter::QueueHandlerImpl::bind(uint16_t /*ticket*/, const string& queueName, @@ -269,17 +280,13 @@ BrokerAdapter::QueueHandlerImpl::unbind(uint16_t /*ticket*/, } -void BrokerAdapter::QueueHandlerImpl::purge(uint16_t /*ticket*/, const string& queueName, bool nowait){ - - Queue::shared_ptr queue = getQueue(queueName); - int count = queue->purge(); - if(!nowait) client.purgeOk( count); +void BrokerAdapter::QueueHandlerImpl::purge(uint16_t /*ticket*/, const string& queue){ + getQueue(queue)->purge(); } void BrokerAdapter::QueueHandlerImpl::delete_(uint16_t /*ticket*/, const string& queue, - bool ifUnused, bool ifEmpty, bool nowait){ + bool ifUnused, bool ifEmpty){ ChannelException error(0, ""); - int count(0); Queue::shared_ptr q = getQueue(queue); if(ifEmpty && q->getMessageCount() > 0){ throw ChannelException(406, "Queue not empty."); @@ -291,14 +298,10 @@ void BrokerAdapter::QueueHandlerImpl::delete_(uint16_t /*ticket*/, const string& QueueVector::iterator i = find(connection.exclusiveQueues.begin(), connection.exclusiveQueues.end(), q); if(i < connection.exclusiveQueues.end()) connection.exclusiveQueues.erase(i); } - count = q->getMessageCount(); q->destroy(); broker.getQueues().destroy(queue); q->unbind(broker.getExchanges(), q); } - - if(!nowait) - client.deleteOk(count); } @@ -333,10 +336,8 @@ void BrokerAdapter::BasicHandlerImpl::consume(uint16_t /*ticket*/, queue->requestDispatch(); } -void BrokerAdapter::BasicHandlerImpl::cancel(const string& consumerTag, bool nowait){ +void BrokerAdapter::BasicHandlerImpl::cancel(const string& consumerTag){ channel.cancel(consumerTag); - - if(!nowait) client.cancelOk(consumerTag); } void BrokerAdapter::BasicHandlerImpl::publish(uint16_t /*ticket*/, diff --git a/cpp/src/qpid/broker/BrokerAdapter.h b/cpp/src/qpid/broker/BrokerAdapter.h index 3fe2eb9eba..99b7f14525 100644 --- a/cpp/src/qpid/broker/BrokerAdapter.h +++ b/cpp/src/qpid/broker/BrokerAdapter.h @@ -121,7 +121,7 @@ class BrokerAdapter : public CoreRefs, public framing::AMQP_ServerOperations const qpid::framing::FieldTable& arguments); void delete_(uint16_t ticket, const std::string& exchange, bool ifUnused); - void query(u_int16_t ticket, const string& name); + framing::ExchangeQueryResult query(u_int16_t ticket, const string& name); private: void checkType(Exchange::shared_ptr exchange, const std::string& type); void checkAlternate(Exchange::shared_ptr exchange, Exchange::shared_ptr alternate); @@ -134,11 +134,11 @@ class BrokerAdapter : public CoreRefs, public framing::AMQP_ServerOperations public: BindingHandlerImpl(BrokerAdapter& parent) : HandlerImplType(parent) {} - void query(u_int16_t ticket, - const std::string& exchange, - const std::string& queue, - const std::string& routingKey, - const framing::FieldTable& arguments); + framing::BindingQueryResult query(u_int16_t ticket, + const std::string& exchange, + const std::string& queue, + const std::string& routingKey, + const framing::FieldTable& arguments); }; class QueueHandlerImpl : @@ -151,7 +151,7 @@ class BrokerAdapter : public CoreRefs, public framing::AMQP_ServerOperations void declare(uint16_t ticket, const std::string& queue, const std::string& alternateExchange, bool passive, bool durable, bool exclusive, - bool autoDelete, bool nowait, + bool autoDelete, const qpid::framing::FieldTable& arguments); void bind(uint16_t ticket, const std::string& queue, const std::string& exchange, const std::string& routingKey, @@ -161,11 +161,10 @@ class BrokerAdapter : public CoreRefs, public framing::AMQP_ServerOperations const std::string& exchange, const std::string& routingKey, const qpid::framing::FieldTable& arguments ); - void purge(uint16_t ticket, const std::string& queue, - bool nowait); + framing::QueueQueryResult query(const string& queue); + void purge(uint16_t ticket, const std::string& queue); void delete_(uint16_t ticket, const std::string& queue, - bool ifUnused, bool ifEmpty, - bool nowait); + bool ifUnused, bool ifEmpty); }; class BasicHandlerImpl : @@ -179,18 +178,15 @@ class BrokerAdapter : public CoreRefs, public framing::AMQP_ServerOperations void qos(uint32_t prefetchSize, uint16_t prefetchCount, bool global); - void consume( - uint16_t ticket, const std::string& queue, - const std::string& consumerTag, bool noLocal, bool noAck, - bool exclusive, bool nowait, - const qpid::framing::FieldTable& fields); - void cancel(const std::string& consumerTag, - bool nowait); + void consume(uint16_t ticket, const std::string& queue, + const std::string& consumerTag, + bool noLocal, bool noAck, bool exclusive, bool nowait, + const qpid::framing::FieldTable& fields); + void cancel(const std::string& consumerTag); void publish(uint16_t ticket, const std::string& exchange, const std::string& routingKey, bool rejectUnroutable, bool immediate); - void get(uint16_t ticket, const std::string& queue, - bool noAck); + void get(uint16_t ticket, const std::string& queue, bool noAck); void ack(uint64_t deliveryTag, bool multiple); void reject(uint64_t deliveryTag, bool requeue); void recover(bool requeue); diff --git a/cpp/src/qpid/broker/BrokerChannel.cpp b/cpp/src/qpid/broker/BrokerChannel.cpp index e135e960c4..0dc4bed661 100644 --- a/cpp/src/qpid/broker/BrokerChannel.cpp +++ b/cpp/src/qpid/broker/BrokerChannel.cpp @@ -374,7 +374,7 @@ void Channel::ack(DeliveryId first, DeliveryId last, bool cumulative) //just acked single element (move end past it) ++end; } - + for_each(start, end, boost::bind(&Channel::acknowledged, this, _1)); if (txBuffer.get()) { diff --git a/cpp/src/qpid/broker/BrokerQueue.h b/cpp/src/qpid/broker/BrokerQueue.h index 857a7adfc2..35aa954c1e 100644 --- a/cpp/src/qpid/broker/BrokerQueue.h +++ b/cpp/src/qpid/broker/BrokerQueue.h @@ -145,8 +145,10 @@ namespace qpid { inline const string& getName() const { return name; } inline const bool isExclusiveOwner(const ConnectionToken* const o) const { return o == owner; } inline bool hasExclusiveConsumer() const { return exclusive; } + inline bool hasExclusiveOwner() const { return owner != 0; } inline bool isDurable() const { return store != 0; } - + inline const framing::FieldTable& getSettings() const { return settings; } + inline bool isAutoDelete() const { return autodelete; } bool canAutoDelete() const; bool enqueue(TransactionContext* ctxt, Message::shared_ptr& msg); diff --git a/cpp/src/qpid/broker/DtxHandlerImpl.cpp b/cpp/src/qpid/broker/DtxHandlerImpl.cpp index 8b3629dff9..5a69ff0d65 100644 --- a/cpp/src/qpid/broker/DtxHandlerImpl.cpp +++ b/cpp/src/qpid/broker/DtxHandlerImpl.cpp @@ -22,19 +22,9 @@ #include "BrokerChannel.h" using namespace qpid::broker; -using qpid::framing::AMQP_ClientProxy; -using qpid::framing::Buffer; -using qpid::framing::FieldTable; +using namespace qpid::framing; using std::string; -DtxHandlerImpl::DtxHandlerImpl(CoreRefs& parent) : - CoreRefs(parent), - dClient(AMQP_ClientProxy::DtxDemarcation::get(proxy)), - cClient(AMQP_ClientProxy::DtxCoordination::get(proxy)) - -{ -} - const int XA_RBROLLBACK(1); const int XA_RBTIMEOUT(2); const int XA_HEURHAZ(3); @@ -44,6 +34,7 @@ const int XA_HEURMIX(6); const int XA_RDONLY(7); const int XA_OK(8); +DtxHandlerImpl::DtxHandlerImpl(CoreRefs& parent) : CoreRefs(parent) {} // DtxDemarcationHandler: @@ -53,10 +44,10 @@ void DtxHandlerImpl::select() channel.selectDtx(); } -void DtxHandlerImpl::end(u_int16_t /*ticket*/, - const string& xid, - bool fail, - bool suspend) +DtxDemarcationEndResult DtxHandlerImpl::end(u_int16_t /*ticket*/, + const string& xid, + bool fail, + bool suspend) { try { if (fail) { @@ -64,7 +55,7 @@ void DtxHandlerImpl::end(u_int16_t /*ticket*/, if (suspend) { throw ConnectionException(503, "End and suspend cannot both be set."); } else { - dClient.endOk(XA_RBROLLBACK); + return DtxDemarcationEndResult(XA_RBROLLBACK); } } else { if (suspend) { @@ -72,14 +63,14 @@ void DtxHandlerImpl::end(u_int16_t /*ticket*/, } else { channel.endDtx(xid, false); } - dClient.endOk(XA_OK); + return DtxDemarcationEndResult(XA_OK); } } catch (const DtxTimeoutException& e) { - dClient.endOk(XA_RBTIMEOUT); + return DtxDemarcationEndResult(XA_RBTIMEOUT); } } -void DtxHandlerImpl::start(u_int16_t /*ticket*/, +DtxDemarcationStartResult DtxHandlerImpl::start(u_int16_t /*ticket*/, const string& xid, bool join, bool resume) @@ -93,52 +84,52 @@ void DtxHandlerImpl::start(u_int16_t /*ticket*/, } else { channel.startDtx(xid, broker.getDtxManager(), join); } - dClient.startOk(XA_OK); + return DtxDemarcationStartResult(XA_OK); } catch (const DtxTimeoutException& e) { - dClient.startOk(XA_RBTIMEOUT); + return DtxDemarcationStartResult(XA_RBTIMEOUT); } } // DtxCoordinationHandler: -void DtxHandlerImpl::prepare(u_int16_t /*ticket*/, +DtxCoordinationPrepareResult DtxHandlerImpl::prepare(u_int16_t /*ticket*/, const string& xid) { try { bool ok = broker.getDtxManager().prepare(xid); - cClient.prepareOk(ok ? XA_OK : XA_RBROLLBACK); + return DtxCoordinationPrepareResult(ok ? XA_OK : XA_RBROLLBACK); } catch (const DtxTimeoutException& e) { - cClient.prepareOk(XA_RBTIMEOUT); + return DtxCoordinationPrepareResult(XA_RBTIMEOUT); } } -void DtxHandlerImpl::commit(u_int16_t /*ticket*/, +DtxCoordinationCommitResult DtxHandlerImpl::commit(u_int16_t /*ticket*/, const string& xid, bool onePhase) { try { bool ok = broker.getDtxManager().commit(xid, onePhase); - cClient.commitOk(ok ? XA_OK : XA_RBROLLBACK); + return DtxCoordinationCommitResult(ok ? XA_OK : XA_RBROLLBACK); } catch (const DtxTimeoutException& e) { - cClient.commitOk(XA_RBTIMEOUT); + return DtxCoordinationCommitResult(XA_RBTIMEOUT); } } -void DtxHandlerImpl::rollback(u_int16_t /*ticket*/, +DtxCoordinationRollbackResult DtxHandlerImpl::rollback(u_int16_t /*ticket*/, const string& xid ) { try { broker.getDtxManager().rollback(xid); - cClient.rollbackOk(XA_OK); + return DtxCoordinationRollbackResult(XA_OK); } catch (const DtxTimeoutException& e) { - cClient.rollbackOk(XA_RBTIMEOUT); + return DtxCoordinationRollbackResult(XA_RBTIMEOUT); } } -void DtxHandlerImpl::recover(u_int16_t /*ticket*/, - bool /*startscan*/, - bool /*endscan*/ ) +DtxCoordinationRecoverResult DtxHandlerImpl::recover(u_int16_t /*ticket*/, + bool /*startscan*/, + bool /*endscan*/ ) { //TODO: what do startscan and endscan actually mean? @@ -169,7 +160,7 @@ void DtxHandlerImpl::recover(u_int16_t /*ticket*/, FieldTable response; response.setString("xids", data); - cClient.recoverOk(response); + return DtxCoordinationRecoverResult(response); } void DtxHandlerImpl::forget(u_int16_t /*ticket*/, @@ -179,10 +170,10 @@ void DtxHandlerImpl::forget(u_int16_t /*ticket*/, throw ConnectionException(503, boost::format("Forget is invalid. Branch with xid %1% not heuristically completed!") % xid); } -void DtxHandlerImpl::getTimeout(const string& xid) +DtxCoordinationGetTimeoutResult DtxHandlerImpl::getTimeout(const string& xid) { uint32_t timeout = broker.getDtxManager().getTimeout(xid); - cClient.getTimeoutOk(timeout); + return DtxCoordinationGetTimeoutResult(timeout); } diff --git a/cpp/src/qpid/broker/DtxHandlerImpl.h b/cpp/src/qpid/broker/DtxHandlerImpl.h index 067ba47fb5..da6379b26c 100644 --- a/cpp/src/qpid/broker/DtxHandlerImpl.h +++ b/cpp/src/qpid/broker/DtxHandlerImpl.h @@ -31,34 +31,34 @@ class DtxHandlerImpl public framing::AMQP_ServerOperations::DtxCoordinationHandler, public framing::AMQP_ServerOperations::DtxDemarcationHandler { - framing::AMQP_ClientProxy::DtxDemarcation dClient; - framing::AMQP_ClientProxy::DtxCoordination cClient; public: DtxHandlerImpl(CoreRefs& parent); // DtxCoordinationHandler: - void commit(u_int16_t ticket, const std::string& xid, bool onePhase); + framing::DtxCoordinationCommitResult commit(u_int16_t ticket, const std::string& xid, bool onePhase); void forget(u_int16_t ticket, const std::string& xid); - void getTimeout(const std::string& xid); + framing::DtxCoordinationGetTimeoutResult getTimeout(const std::string& xid); - void prepare(u_int16_t ticket, const std::string& xid); + framing::DtxCoordinationPrepareResult prepare(u_int16_t ticket, const std::string& xid); - void recover(u_int16_t ticket, bool startscan, bool endscan); + framing::DtxCoordinationRecoverResult recover(u_int16_t ticket, bool startscan, bool endscan); - void rollback(u_int16_t ticket, const std::string& xid); + framing::DtxCoordinationRollbackResult rollback(u_int16_t ticket, const std::string& xid); void setTimeout(u_int16_t ticket, const std::string& xid, u_int32_t timeout); // DtxDemarcationHandler: - - void end(u_int16_t ticket, const std::string& xid, bool fail, bool suspend); - + + framing::DtxDemarcationEndResult end(u_int16_t ticket, const std::string& xid, bool fail, bool suspend); + void select(); + + framing::DtxDemarcationStartResult start(u_int16_t ticket, const std::string& xid, bool join, bool resume); + - void start(u_int16_t ticket, const std::string& xid, bool join, bool resume); }; diff --git a/cpp/src/qpid/broker/MessageHandlerImpl.cpp b/cpp/src/qpid/broker/MessageHandlerImpl.cpp index 3f407c11f7..ce1fa1e028 100644 --- a/cpp/src/qpid/broker/MessageHandlerImpl.cpp +++ b/cpp/src/qpid/broker/MessageHandlerImpl.cpp @@ -87,19 +87,21 @@ MessageHandlerImpl::offset(uint64_t /*value*/ ) } void -MessageHandlerImpl::consume(uint16_t /*ticket*/, +MessageHandlerImpl::subscribe(uint16_t /*ticket*/, const string& queueName, const string& destination, bool noLocal, - bool noAck, + u_int8_t confirmMode, + u_int8_t /*acquireMode*/,//TODO: implement acquire modes bool exclusive, const framing::FieldTable& filter ) { Queue::shared_ptr queue = getQueue(queueName); if(!destination.empty() && channel.exists(destination)) throw ConnectionException(530, "Consumer tags must be unique"); + string tag = destination; - channel.consume(MessageMessage::getToken(destination), tag, queue, noLocal, !noAck, exclusive, &filter); + channel.consume(MessageMessage::getToken(destination), tag, queue, noLocal, confirmMode == 1, exclusive, &filter); // Dispatch messages as there is now a consumer. queue->requestDispatch(); } @@ -153,8 +155,9 @@ MessageHandlerImpl::recover(bool requeue) } void -MessageHandlerImpl::reject(uint16_t /*code*/, const string& /*text*/ ) +MessageHandlerImpl::reject(const SequenceNumberSet& /*transfers*/, uint16_t /*code*/, const string& /*text*/ ) { + //TODO: implement } void @@ -210,5 +213,14 @@ void MessageHandlerImpl::stop(const std::string& destination) channel.stop(destination); } +void MessageHandlerImpl::acquire(const SequenceNumberSet& /*transfers*/, u_int8_t /*mode*/) +{ + throw ConnectionException(540, "Not yet implemented"); +} + +void MessageHandlerImpl::release(const SequenceNumberSet& /*transfers*/) +{ + throw ConnectionException(540, "Not yet implemented"); +} }} // namespace qpid::broker diff --git a/cpp/src/qpid/broker/MessageHandlerImpl.h b/cpp/src/qpid/broker/MessageHandlerImpl.h index 20cae46da4..f4d9fa0c76 100644 --- a/cpp/src/qpid/broker/MessageHandlerImpl.h +++ b/cpp/src/qpid/broker/MessageHandlerImpl.h @@ -49,14 +49,6 @@ class MessageHandlerImpl : void close(const std::string& reference ); - void consume(uint16_t ticket, - const std::string& queue, - const std::string& destination, - bool noLocal, - bool noAck, - bool exclusive, - const framing::FieldTable& filter ); - void empty(); void get(uint16_t ticket, @@ -76,8 +68,9 @@ class MessageHandlerImpl : void recover(bool requeue ); - void reject(uint16_t code, - const std::string& text ); + void reject(const framing::SequenceNumberSet& transfers, + uint16_t code, + const std::string& text ); void resume(const std::string& reference, const std::string& identifier ); @@ -92,6 +85,19 @@ class MessageHandlerImpl : void stop(const std::string& destination); + void acquire(const framing::SequenceNumberSet& transfers, u_int8_t mode); + + void release(const framing::SequenceNumberSet& transfers); + + void subscribe(u_int16_t ticket, + const string& queue, + const string& destination, + bool noLocal, + u_int8_t confirmMode, + u_int8_t acquireMode, + bool exclusive, + const framing::FieldTable& filter); + private: ReferenceRegistry references; }; diff --git a/cpp/src/qpid/broker/SemanticHandler.cpp b/cpp/src/qpid/broker/SemanticHandler.cpp index b7aa2aad25..f65e450e82 100644 --- a/cpp/src/qpid/broker/SemanticHandler.cpp +++ b/cpp/src/qpid/broker/SemanticHandler.cpp @@ -22,8 +22,10 @@ #include "SemanticHandler.h" #include "BrokerAdapter.h" #include "qpid/framing/ChannelAdapter.h" -#include "qpid/framing/ExecutionCompleteBody.h" #include "qpid/framing/ChannelCloseOkBody.h" +#include "qpid/framing/ExecutionCompleteBody.h" +#include "qpid/framing/ExecutionResultBody.h" +#include "qpid/framing/InvocationVisitor.h" using namespace qpid::broker; using namespace qpid::framing; @@ -66,6 +68,11 @@ void SemanticHandler::handleMethod(framing::AMQMethodBody* method) { try { if (!method->invoke(this)) { + //temporary hack until channel management is moved to its own handler: + if (method->amqpClassId() != ChannelOpenBody::CLASS_ID) { + ++(incoming.lwm); + } + //else do the usual: handleL4(method); //(if the frameset is complete) we can move the execution-mark @@ -73,7 +80,9 @@ void SemanticHandler::handleMethod(framing::AMQMethodBody* method) //temporary hack until channel management is moved to its own handler: if (method->amqpClassId() != ChannelOpenBody::CLASS_ID) { - ++(incoming.hwm); + //TODO: need to account for async store opreations + //when this command is a message publication + ++(incoming.hwm); } //note: need to be more sophisticated than this if we execute @@ -85,7 +94,7 @@ void SemanticHandler::handleMethod(framing::AMQMethodBody* method) } } -void SemanticHandler::complete(uint32_t cumulative, SequenceNumberSet range) +void SemanticHandler::complete(uint32_t cumulative, const SequenceNumberSet& range) { //record: SequenceNumber mark(cumulative); @@ -98,7 +107,7 @@ void SemanticHandler::complete(uint32_t cumulative, SequenceNumberSet range) if (range.size() % 2) { //must be even number throw ConnectionException(530, "Received odd number of elements in ranged mark"); } else { - for (SequenceNumberSet::iterator i = range.begin(); i != range.end(); i++) { + for (SequenceNumberSet::const_iterator i = range.begin(); i != range.end(); i++) { channel.ackRange((uint64_t) i->getValue(), (uint64_t) (++i)->getValue()); } } @@ -113,6 +122,25 @@ void SemanticHandler::flush() ChannelAdapter::send(ExecutionCompleteBody(getVersion(), incoming.hwm.getValue(), SequenceNumberSet())); } } +void SemanticHandler::sync() +{ + //for now, just treat as flush; will need to get more clever when we deal with async publication + flush(); +} + +void SemanticHandler::noop() +{ + //Do nothing... + // + //is this an L3 control? or is it an L4 command? + //if the former, of what use is it? + //if the latter it may contain a synch request... but its odd to have it in this class +} + +void SemanticHandler::result(uint32_t /*command*/, const std::string& /*data*/) +{ + //never actually sent by client at present +} void SemanticHandler::handleL4(framing::AMQMethodBody* method) { @@ -124,7 +152,13 @@ void SemanticHandler::handleL4(framing::AMQMethodBody* method) throw ConnectionException(504, out.str()); } } else { - method->invoke(*adapter); + InvocationVisitor v(adapter.get()); + method->accept(v); + if (!v.wasHandled()) { + throw ConnectionException(540, "Not implemented"); + } else if (v.hasResult()) { + ChannelAdapter::send(ExecutionResultBody(getVersion(), incoming.lwm.getValue(), v.getResult())); + } } }catch(const ChannelException& e){ adapter->getProxy().getChannel().close( diff --git a/cpp/src/qpid/broker/SemanticHandler.h b/cpp/src/qpid/broker/SemanticHandler.h index 6748da8500..672c6ad929 100644 --- a/cpp/src/qpid/broker/SemanticHandler.h +++ b/cpp/src/qpid/broker/SemanticHandler.h @@ -79,8 +79,11 @@ public: void handle(framing::AMQFrame& frame); //execution class method handlers: - void complete(uint32_t cumulativeExecutionMark, framing::SequenceNumberSet range); + void complete(uint32_t cumulativeExecutionMark, const framing::SequenceNumberSet& range); void flush(); + void noop(); + void result(uint32_t command, const std::string& data); + void sync(); }; }} diff --git a/cpp/src/qpid/client/ClientChannel.cpp b/cpp/src/qpid/client/ClientChannel.cpp index aa73e83328..d1cc4734eb 100644 --- a/cpp/src/qpid/client/ClientChannel.cpp +++ b/cpp/src/qpid/client/ClientChannel.cpp @@ -20,6 +20,7 @@ */ #include "qpid/log/Statement.h" #include +#include #include "ClientChannel.h" #include "qpid/sys/Monitor.h" #include "ClientMessage.h" @@ -54,7 +55,8 @@ class ScopedSync }; Channel::Channel(bool _transactional, u_int16_t _prefetch) : - prefetch(_prefetch), transactional(_transactional), running(false) + prefetch(_prefetch), transactional(_transactional), running(false), + uniqueId(true)/*could eventually be the session id*/, nameCounter(0) { } @@ -103,20 +105,22 @@ void Channel::deleteExchange(Exchange& exchange, bool synch){ } void Channel::declareQueue(Queue& queue, bool synch){ + if (queue.getName().empty()) { + stringstream uniqueName; + uniqueName << uniqueId << "-queue-" << ++nameCounter; + queue.setName(uniqueName.str()); + } + FieldTable args; ScopedSync s(*session, synch); - Response r = session->queueDeclare(0, queue.getName(), empty, false/*passive*/, queue.isDurable(), - queue.isExclusive(), queue.isAutoDelete(), !synch, args); + session->queueDeclare(0, queue.getName(), empty, false/*passive*/, queue.isDurable(), + queue.isExclusive(), queue.isAutoDelete(), args); - if(synch) { - if(queue.getName().length() == 0) - queue.setName(r.as().getQueue()); - } } void Channel::deleteQueue(Queue& queue, bool ifunused, bool ifempty, bool synch){ ScopedSync s(*session, synch); - session->queueDelete(0, queue.getName(), ifunused, ifempty, !synch); + session->queueDelete(0, queue.getName(), ifunused, ifempty); } void Channel::bind(const Exchange& exchange, const Queue& queue, const std::string& key, const FieldTable& args, bool synch){ @@ -168,7 +172,7 @@ void Channel::cancel(const std::string& tag, bool synch) { consumers.erase(i); } ScopedSync s(*session, synch); - session->basicCancel(tag, !synch); + session->basicCancel(tag); } bool Channel::get(Message& msg, const Queue& queue, AckMode ackMode) { diff --git a/cpp/src/qpid/client/ClientChannel.h b/cpp/src/qpid/client/ClientChannel.h index 98e04db109..d73addc950 100644 --- a/cpp/src/qpid/client/ClientChannel.h +++ b/cpp/src/qpid/client/ClientChannel.h @@ -24,11 +24,12 @@ #include #include #include "qpid/framing/amqp_framing.h" +#include "qpid/framing/Uuid.h" #include "ClientExchange.h" #include "ClientMessage.h" #include "ClientQueue.h" #include "ConnectionImpl.h" -#include "Session.h" +#include "qpid/client/Session.h" #include "qpid/Exception.h" #include "qpid/sys/Mutex.h" #include "qpid/sys/Runnable.h" @@ -83,6 +84,8 @@ class Channel : private sys::Runnable SessionCore::shared_ptr sessionCore; framing::ChannelId channelId; BlockingQueue gets; + framing::Uuid uniqueId; + uint32_t nameCounter; void stop(); diff --git a/cpp/src/qpid/client/Connection.h b/cpp/src/qpid/client/Connection.h index e41ab363b5..e309b5c63e 100644 --- a/cpp/src/qpid/client/Connection.h +++ b/cpp/src/qpid/client/Connection.h @@ -26,7 +26,7 @@ #include "qpid/QpidError.h" #include "ClientChannel.h" #include "ConnectionImpl.h" -#include "Session.h" +#include "qpid/client/Session.h" #include "qpid/framing/AMQP_HighestVersion.h" diff --git a/cpp/src/qpid/client/ExecutionHandler.cpp b/cpp/src/qpid/client/ExecutionHandler.cpp index 6ee6429b6b..6c2600d00b 100644 --- a/cpp/src/qpid/client/ExecutionHandler.cpp +++ b/cpp/src/qpid/client/ExecutionHandler.cpp @@ -78,7 +78,7 @@ void ExecutionHandler::handle(AMQFrame& frame) } } -void ExecutionHandler::complete(uint32_t cumulative, SequenceNumberSet range) +void ExecutionHandler::complete(uint32_t cumulative, const SequenceNumberSet& range) { SequenceNumber mark(cumulative); if (outgoing.lwm < mark) { @@ -101,6 +101,26 @@ void ExecutionHandler::flush() incoming.lwm = incoming.hwm; } +void ExecutionHandler::noop() +{ + //do nothing +} + +void ExecutionHandler::result(uint32_t /*command*/, const std::string& /*data*/) +{ + //TODO: need to signal the result to the appropriate listener +} + +void ExecutionHandler::sync() +{ + //TODO: implement (the application is in charge of completion of + //some commands, so need to track completion for them). + + //This shouldn't ever need to be called by the server (in my + //opinion) as the server never needs to synchronise with the + //clients execution +} + void ExecutionHandler::sendFlush() { AMQFrame frame(version, 0, ExecutionFlushBody()); diff --git a/cpp/src/qpid/client/ExecutionHandler.h b/cpp/src/qpid/client/ExecutionHandler.h index 21613df779..b409d5df7b 100644 --- a/cpp/src/qpid/client/ExecutionHandler.h +++ b/cpp/src/qpid/client/ExecutionHandler.h @@ -45,8 +45,11 @@ class ExecutionHandler : framing::ProtocolVersion version; uint64_t maxFrameSize; - void complete(uint32_t mark, framing::SequenceNumberSet range); + void complete(uint32_t mark, const framing::SequenceNumberSet& range); void flush(); + void noop(); + void result(uint32_t command, const std::string& data); + void sync(); public: BlockingQueue received; diff --git a/cpp/src/qpid/framing/AMQP_HighestVersion.h b/cpp/src/qpid/framing/AMQP_HighestVersion.h new file mode 100644 index 0000000000..42139c7937 --- /dev/null +++ b/cpp/src/qpid/framing/AMQP_HighestVersion.h @@ -0,0 +1,40 @@ +/* + * + * 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 used to be auto-generated by Qpid Gentools v.0.1 + * its here temporarily until we get a full solution to multi-version support + */ +#ifndef qpid_framing_highestProtocolVersion__ +#define qpid_framing_highestProtocolVersion__ + +#include "qpid/framing/ProtocolVersion.h" + + +namespace qpid { +namespace framing { + +static ProtocolVersion highestProtocolVersion(0, 10); + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/cpp/src/qpid/framing/StructHelper.h b/cpp/src/qpid/framing/StructHelper.h new file mode 100644 index 0000000000..b5d1b1e78c --- /dev/null +++ b/cpp/src/qpid/framing/StructHelper.h @@ -0,0 +1,56 @@ +/* + * + * 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. + * + */ +#ifndef _StructHelper_ +#define _StructHelper_ + +#include "qpid/Exception.h" + +namespace qpid { +namespace framing { + +class StructHelper +{ +public: + + template void encode(const T t, std::string& data) { + uint32_t size = t.size() + 2/*type*/; + Buffer buffer(size); + buffer.putShort(T::TYPE); + t.encode(buffer); + buffer.flip(); + buffer.getRawData(data, size); + } + + template void decode(T t, std::string& data) { + Buffer buffer(data.length()); + buffer.putRawData(data); + buffer.flip(); + uint16_t type = buffer.getShort(); + if (type == T::TYPE) { + t.decode(buffer); + } else { + throw Exception("Type code does not match"); + } + } +}; + +}} +#endif diff --git a/cpp/src/qpid/framing/amqp_types_full.h b/cpp/src/qpid/framing/amqp_types_full.h index 6a24a99d38..027b563caf 100644 --- a/cpp/src/qpid/framing/amqp_types_full.h +++ b/cpp/src/qpid/framing/amqp_types_full.h @@ -32,5 +32,6 @@ #include "amqp_types.h" #include "FramingContent.h" #include "FieldTable.h" +#include "SequenceNumberSet.h" #endif /*!_framing_amqp_types_decl_h*/ diff --git a/cpp/src/tests/Blob b/cpp/src/tests/Blob deleted file mode 100755 index 05e67dc01f..0000000000 Binary files a/cpp/src/tests/Blob and /dev/null differ diff --git a/cpp/src/tests/Cluster_child.cpp b/cpp/src/tests/Cluster_child.cpp index 62ccb9bd72..7789ada614 100644 --- a/cpp/src/tests/Cluster_child.cpp +++ b/cpp/src/tests/Cluster_child.cpp @@ -32,7 +32,7 @@ using namespace qpid::log; static const ProtocolVersion VER; -/** Chlid part of Cluster::clusterTwo test */ +/** Child part of Cluster::clusterTwo test */ void clusterTwo() { TestCluster cluster("clusterTwo", "amqp:child:2"); AMQFrame frame; -- cgit v1.2.1