From 3fb9be28593263e12623ce09084a230b59b81f4f Mon Sep 17 00:00:00 2001 From: Robert Godfrey Date: Thu, 22 Mar 2007 13:14:42 +0000 Subject: made a copy git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/branches/java.multi_version@521253 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/qpid/gentools/AmqpClass.java | 285 +- .../src/org/apache/qpid/gentools/AmqpClassMap.java | 2 +- .../src/org/apache/qpid/gentools/AmqpConstant.java | 134 +- .../org/apache/qpid/gentools/AmqpConstantSet.java | 115 +- .../src/org/apache/qpid/gentools/AmqpDomain.java | 103 +- .../org/apache/qpid/gentools/AmqpDomainMap.java | 181 +- .../apache/qpid/gentools/AmqpDomainVersionMap.java | 64 +- .../src/org/apache/qpid/gentools/AmqpField.java | 350 +- .../src/org/apache/qpid/gentools/AmqpFieldMap.java | 728 +++-- .../src/org/apache/qpid/gentools/AmqpFlagMap.java | 90 +- .../src/org/apache/qpid/gentools/AmqpMethod.java | 444 ++- .../org/apache/qpid/gentools/AmqpMethodMap.java | 14 +- .../src/org/apache/qpid/gentools/AmqpModel.java | 149 +- .../apache/qpid/gentools/AmqpOrdinalFieldMap.java | 125 +- .../qpid/gentools/AmqpOrdinalVersionMap.java | 72 +- .../apache/qpid/gentools/AmqpParseException.java | 10 +- .../qpid/gentools/AmqpTemplateException.java | 10 +- .../qpid/gentools/AmqpTypeMappingException.java | 10 +- .../src/org/apache/qpid/gentools/AmqpVersion.java | 88 +- .../org/apache/qpid/gentools/AmqpVersionSet.java | 39 +- .../src/org/apache/qpid/gentools/CppGenerator.java | 2710 ++++++++-------- .../org/apache/qpid/gentools/DotnetGenerator.java | 614 ++-- .../src/org/apache/qpid/gentools/Generator.java | 1200 ++++--- .../org/apache/qpid/gentools/JavaGenerator.java | 3374 ++++++++++---------- .../apache/qpid/gentools/LanguageConverter.java | 31 +- gentools/src/org/apache/qpid/gentools/Main.java | 434 ++- .../src/org/apache/qpid/gentools/NodeAware.java | 33 +- .../src/org/apache/qpid/gentools/Printable.java | 2 +- .../qpid/gentools/TargetDirectoryException.java | 10 +- gentools/src/org/apache/qpid/gentools/Utils.java | 191 +- .../qpid/gentools/VersionConsistencyCheck.java | 2 +- gentools/templ.cpp/AMQP_ClientOperations.h.tmpl | 82 - gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl | 52 - gentools/templ.cpp/AMQP_ClientProxy.h.tmpl | 75 - gentools/templ.cpp/AMQP_Constants.h.tmpl | 34 - gentools/templ.cpp/AMQP_HighestVersion.h.tmpl | 42 - gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl | 62 - gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl | 57 - gentools/templ.cpp/AMQP_ServerOperations.h.tmpl | 83 - gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl | 51 - gentools/templ.cpp/AMQP_ServerProxy.h.tmpl | 74 - gentools/templ.cpp/MethodBodyClass.h.tmpl | 112 - gentools/templ.cpp/method/MethodBodyClass.h.tmpl | 112 + .../templ.cpp/model/AMQP_ClientOperations.h.tmpl | 82 + gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl | 52 + gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl | 75 + gentools/templ.cpp/model/AMQP_Constants.h.tmpl | 34 + .../templ.cpp/model/AMQP_HighestVersion.h.tmpl | 42 + .../templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl | 62 + .../templ.cpp/model/AMQP_MethodVersionMap.h.tmpl | 57 + .../templ.cpp/model/AMQP_ServerOperations.h.tmpl | 83 + gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl | 51 + gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl | 74 + gentools/templ.java/AmqpConstantsClass.tmpl | 37 - gentools/templ.java/MethodBodyClass.tmpl | 183 -- gentools/templ.java/MethodRegistryClass.tmpl | 153 - gentools/templ.java/ProtocolVersionListClass.tmpl | 38 - .../templ.java/model/ProtocolVersionListClass.vm | 148 + .../templ.java/model/version/AmqpConstantsClass.vm | 37 + .../model/version/MethodRegistryClass.vm | 136 + java/broker/bin/qpid-server-bdb.bat | 2 +- .../src/main/assembly/broker-bin-tests.xml | 2 +- java/broker/etc/config.xml | 13 +- java/broker/etc/log4j.xml | 18 +- java/broker/etc/virtualhosts.xml | 9 +- .../java/org/apache/qpid/server/AMQChannel.java | 9 +- .../src/main/java/org/apache/qpid/server/Main.java | 24 +- .../server/ack/UnacknowledgedMessageMapImpl.java | 2 +- .../qpid/server/filter/PropertyExpression.java | 31 +- .../qpid/server/handler/BasicAckMethodHandler.java | 2 +- .../server/handler/BasicCancelMethodHandler.java | 6 +- .../server/handler/BasicConsumeMethodHandler.java | 18 +- .../qpid/server/handler/BasicGetMethodHandler.java | 10 +- .../server/handler/BasicPublishMethodHandler.java | 8 +- .../qpid/server/handler/BasicQosHandler.java | 4 +- .../server/handler/BasicRecoverMethodHandler.java | 2 +- .../server/handler/BasicRejectMethodHandler.java | 4 +- .../qpid/server/handler/ChannelCloseHandler.java | 4 +- .../qpid/server/handler/ChannelFlowHandler.java | 6 +- .../qpid/server/handler/ChannelOpenHandler.java | 16 +- .../handler/ConnectionCloseMethodHandler.java | 4 +- .../handler/ConnectionOpenMethodHandler.java | 8 +- .../handler/ConnectionSecureOkMethodHandler.java | 52 +- .../handler/ConnectionStartOkMethodHandler.java | 20 +- .../handler/ConnectionTuneOkMethodHandler.java | 2 +- .../qpid/server/handler/ExchangeBoundHandler.java | 65 +- .../server/handler/ExchangeDeclareHandler.java | 20 +- .../qpid/server/handler/ExchangeDeleteHandler.java | 2 +- .../qpid/server/handler/QueueBindHandler.java | 29 +- .../qpid/server/handler/QueueDeclareHandler.java | 28 +- .../qpid/server/handler/QueueDeleteHandler.java | 16 +- .../qpid/server/handler/QueuePurgeHandler.java | 8 +- .../qpid/server/handler/TxRollbackHandler.java | 15 +- .../qpid/server/handler/TxSelectHandler.java | 13 +- .../server/output/ProtocolOutputConverter.java | 57 + .../output/ProtocolOutputConverterRegistry.java | 62 + .../amqp0_8/ProtocolOutputConverterImpl.java | 288 ++ .../server/protocol/AMQMinaProtocolSession.java | 266 +- .../protocol/AMQNoMethodHandlerException.java | 34 + .../server/protocol/AMQPFastProtocolHandler.java | 15 +- .../qpid/server/protocol/AMQProtocolSession.java | 3 + .../server/protocol/AMQProtocolSessionMBean.java | 26 +- .../protocol/UnknnownMessageTypeException.java | 33 + .../org/apache/qpid/server/queue/AMQMessage.java | 42 +- .../apache/qpid/server/queue/AMQQueueMBean.java | 13 +- .../queue/ConcurrentSelectorDeliveryManager.java | 3 +- .../apache/qpid/server/queue/SubscriptionImpl.java | 16 +- .../apache/qpid/server/state/AMQStateManager.java | 30 +- .../server/state/StateAwareMethodListener.java | 1 + .../qpid/server/store/ContentChunkAdapter.java | 57 - .../server/store/MessagePublishInfoAdapter.java | 62 - .../java/org/apache/qpid/client/AMQConnection.java | 58 +- .../java/org/apache/qpid/client/AMQSession.java | 359 +-- .../apache/qpid/client/BasicMessageConsumer.java | 33 +- .../apache/qpid/client/BasicMessageProducer.java | 159 +- .../qpid/client/failover/FailoverHandler.java | 6 +- .../client/handler/BasicCancelOkMethodHandler.java | 54 - .../client/handler/BasicDeliverMethodHandler.java | 49 - .../client/handler/BasicReturnMethodHandler.java | 50 - .../client/handler/ChannelCloseMethodHandler.java | 99 - .../handler/ChannelCloseOkMethodHandler.java | 47 - .../client/handler/ChannelFlowOkMethodHandler.java | 50 - .../handler/ConnectionCloseMethodHandler.java | 100 - .../handler/ConnectionOpenOkMethodHandler.java | 48 - .../handler/ConnectionRedirectMethodHandler.java | 70 - .../handler/ConnectionSecureMethodHandler.java | 73 - .../handler/ConnectionStartMethodHandler.java | 261 -- .../handler/ConnectionTuneMethodHandler.java | 97 - .../handler/ExchangeBoundOkMethodHandler.java | 56 - .../client/handler/QueueDeleteOkMethodHandler.java | 55 - .../amqp_0_9/ChannelCloseMethodHandler.java | 24 + .../amqp_0_9/ConnectionCloseMethodHandler.java | 29 + .../amqp_0_9/ConnectionSecureMethodHandler.java | 28 + .../amqp_0_9/ConnectionTuneMethodHandler.java | 41 + .../amqp_8_0/BasicCancelOkMethodHandler.java | 56 + .../amqp_8_0/BasicDeliverMethodHandler.java | 50 + .../handler/amqp_8_0/BasicReturnMethodHandler.java | 51 + .../amqp_8_0/ChannelCloseMethodHandler.java | 106 + .../amqp_8_0/ChannelCloseOkMethodHandler.java | 46 + .../amqp_8_0/ChannelFlowOkMethodHandler.java | 49 + .../amqp_8_0/ConnectionCloseMethodHandler.java | 112 + .../amqp_8_0/ConnectionOpenOkMethodHandler.java | 47 + .../amqp_8_0/ConnectionRedirectMethodHandler.java | 71 + .../amqp_8_0/ConnectionSecureMethodHandler.java | 75 + .../amqp_8_0/ConnectionStartMethodHandler.java | 243 ++ .../amqp_8_0/ConnectionTuneMethodHandler.java | 99 + .../amqp_8_0/ExchangeBoundOkMethodHandler.java | 55 + .../amqp_8_0/QueueDeleteOkMethodHandler.java | 54 + .../qpid/client/message/AbstractJMSMessage.java | 12 +- .../apache/qpid/client/message/JMSTextMessage.java | 6 +- .../client/message/MessageFactoryRegistry.java | 4 +- .../qpid/client/protocol/AMQProtocolHandler.java | 636 +--- .../client/protocol/AMQProtocolHandlerImpl.java | 537 ++++ .../qpid/client/protocol/AMQProtocolSession.java | 48 +- .../protocol/BlockingMethodFrameListener.java | 7 +- .../client/protocol/ProtocolOutputHandler.java | 58 + .../protocol/ProtocolOutputHandlerFactory.java | 50 + .../amqp_8_0/ProtocolOutputHandler_8_0.java | 278 ++ .../apache/qpid/client/state/AMQStateManager.java | 44 +- .../client/state/StateAwareMethodListener.java | 4 +- .../listener/SpecificMethodFrameListener.java | 5 +- .../client/transport/ITransportConnection.java | 4 +- .../transport/SocketTransportConnection.java | 4 +- .../transport/VmPipeTransportConnection.java | 4 +- .../org/apache/qpid/codec/BasicDeliverTest.java | 14 +- .../org/apache/qpid/framing/FieldTableTest.java | 4 +- .../ChannelCloseMethodHandlerNoCloseOk.java | 7 +- .../unit/client/channelclose/ChannelCloseTest.java | 39 +- .../client/channelclose/NoCloseOKStateManager.java | 20 +- .../client/protocol/AMQProtocolSessionTest.java | 4 +- .../server/cluster/AMQConnectionWaitException.java | 32 + .../cluster/AMQUnexpectedBodyTypeException.java | 33 + .../cluster/AMQUnexpectedFrameTypeException.java | 31 + .../qpid/server/cluster/BlockingHandler.java | 12 +- .../org/apache/qpid/server/cluster/Broker.java | 12 +- .../apache/qpid/server/cluster/BrokerGroup.java | 4 +- .../apache/qpid/server/cluster/ClientAdapter.java | 4 +- .../qpid/server/cluster/ClientHandlerRegistry.java | 28 +- .../server/cluster/ClusteredProtocolHandler.java | 3 - .../qpid/server/cluster/DefaultGroupManager.java | 2 +- .../apache/qpid/server/cluster/GroupRequest.java | 10 +- .../qpid/server/cluster/GroupResponseHandler.java | 4 +- .../apache/qpid/server/cluster/MethodHandler.java | 4 +- .../qpid/server/cluster/MethodHandlerRegistry.java | 10 +- .../qpid/server/cluster/MinaBrokerProxy.java | 40 +- .../qpid/server/cluster/ResponseHandler.java | 4 +- .../qpid/server/cluster/ServerHandlerRegistry.java | 8 +- .../qpid/server/cluster/SimpleBodySendable.java | 6 +- .../handler/ChainedClusterMethodHandler.java | 8 +- .../cluster/handler/ClusterMethodHandler.java | 6 +- .../handler/ClusterMethodHandlerFactory.java | 6 +- .../server/cluster/handler/ExtendedHandler.java | 7 +- .../qpid/server/cluster/handler/NullListener.java | 7 +- .../qpid/server/cluster/handler/PeerHandler.java | 8 +- .../server/cluster/handler/ReplicatingHandler.java | 6 +- .../server/cluster/handler/WrappedListener.java | 9 +- .../handler/WrappingMethodHandlerFactory.java | 6 +- .../cluster/replay/ChainedMethodRecorder.java | 4 +- .../qpid/server/cluster/replay/ConsumerCounts.java | 6 +- .../qpid/server/cluster/replay/MethodRecorder.java | 4 +- .../replay/RecordingMethodHandlerFactory.java | 9 - .../qpid/server/cluster/replay/ReplayManager.java | 6 +- .../qpid/server/cluster/replay/ReplayStore.java | 14 +- .../org/apache/qpid/server/cluster/BrokerTest.java | 18 +- .../org/apache/qpid/server/cluster/TestBroker.java | 8 +- .../qpid/server/cluster/TestReplayManager.java | 10 +- .../java/org/apache/qpid/AMQChannelException.java | 4 +- .../org/apache/qpid/AMQConnectionException.java | 3 +- .../java/org/apache/qpid/codec/AMQDecoder.java | 16 +- .../org/apache/qpid/common/ClientProperties.java | 20 +- .../main/java/org/apache/qpid/framing/AMQBody.java | 21 +- .../java/org/apache/qpid/framing/AMQBodyImpl.java | 27 + .../apache/qpid/framing/AMQDataBlockDecoder.java | 2 +- .../org/apache/qpid/framing/AMQMethodBody.java | 133 +- .../apache/qpid/framing/AMQMethodBodyFactory.java | 2 +- .../org/apache/qpid/framing/AMQMethodBodyImpl.java | 102 + .../qpid/framing/AMQMethodBodyInstanceFactory.java | 3 +- .../org/apache/qpid/framing/AMQMethodFactory.java | 90 + .../qpid/framing/BasicContentHeaderProperties.java | 125 +- .../framing/CommonContentHeaderProperties.java | 65 + .../java/org/apache/qpid/framing/ContentBody.java | 2 +- .../apache/qpid/framing/ContentBodyFactory.java | 2 +- .../org/apache/qpid/framing/ContentHeaderBody.java | 4 +- .../qpid/framing/ContentHeaderBodyFactory.java | 2 +- .../framing/ContentHeaderPropertiesFactory.java | 4 +- .../java/org/apache/qpid/framing/FieldTable.java | 68 +- .../org/apache/qpid/framing/HeartbeatBody.java | 6 +- .../apache/qpid/framing/HeartbeatBodyFactory.java | 2 +- .../java/org/apache/qpid/framing/MainRegistry.java | 35 + .../apache/qpid/framing/MethodConverter_8_0.java | 22 +- .../apache/qpid/framing/ProtocolInitiation.java | 155 +- .../qpid/framing/VersionSpecificRegistry.java | 2 +- .../abstraction/MessagePublishInfoConverter.java | 3 +- .../ProtocolVersionMethodConverter.java | 3 +- .../qpid/framing/amqp_8_0/AMQMethodBody_8_0.java | 160 + .../framing/amqp_8_0/AMQMethodFactory_8_0.java | 117 + .../java/org/apache/qpid/pool/PoolingFilter.java | 1 + .../org/apache/qpid/protocol/AMQMethodEvent.java | 1 + .../apache/qpid/protocol/AMQMethodListener.java | 4 +- .../protocol/AMQVersionAwareProtocolSession.java | 4 +- .../apache/qpid/protocol/ProtocolVersionAware.java | 5 +- .../framing/BasicContentHeaderPropertiesTest.java | 20 +- .../qpid/server/queue/MockProtocolSession.java | 6 + 243 files changed, 12007 insertions(+), 9646 deletions(-) delete mode 100644 gentools/templ.cpp/AMQP_ClientOperations.h.tmpl delete mode 100644 gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl delete mode 100644 gentools/templ.cpp/AMQP_ClientProxy.h.tmpl delete mode 100644 gentools/templ.cpp/AMQP_Constants.h.tmpl delete mode 100644 gentools/templ.cpp/AMQP_HighestVersion.h.tmpl delete mode 100644 gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl delete mode 100644 gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl delete mode 100644 gentools/templ.cpp/AMQP_ServerOperations.h.tmpl delete mode 100644 gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl delete mode 100644 gentools/templ.cpp/AMQP_ServerProxy.h.tmpl delete mode 100644 gentools/templ.cpp/MethodBodyClass.h.tmpl create mode 100644 gentools/templ.cpp/method/MethodBodyClass.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_Constants.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl create mode 100644 gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl delete mode 100644 gentools/templ.java/AmqpConstantsClass.tmpl delete mode 100644 gentools/templ.java/MethodBodyClass.tmpl delete mode 100644 gentools/templ.java/MethodRegistryClass.tmpl delete mode 100644 gentools/templ.java/ProtocolVersionListClass.tmpl create mode 100644 gentools/templ.java/model/ProtocolVersionListClass.vm create mode 100644 gentools/templ.java/model/version/AmqpConstantsClass.vm create mode 100644 gentools/templ.java/model/version/MethodRegistryClass.vm create mode 100644 java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/AMQNoMethodHandlerException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/UnknnownMessageTypeException.java delete mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/ContentChunkAdapter.java delete mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/MessagePublishInfoAdapter.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java delete mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ChannelCloseMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionCloseMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionSecureMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionTuneMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicCancelOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicDeliverMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicReturnMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelFlowOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionCloseMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionOpenOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionRedirectMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionSecureMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionStartMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionTuneMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ExchangeBoundOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/QueueDeleteOkMethodHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandlerImpl.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandler.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandlerFactory.java create mode 100644 java/client/src/main/java/org/apache/qpid/client/protocol/amqp_8_0/ProtocolOutputHandler_8_0.java create mode 100644 java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQConnectionWaitException.java create mode 100644 java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedBodyTypeException.java create mode 100644 java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedFrameTypeException.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/AMQBodyImpl.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/AMQMethodFactory.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/CommonContentHeaderProperties.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/MainRegistry.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/AMQMethodBody_8_0.java create mode 100644 java/common/src/main/java/org/apache/qpid/framing/amqp_8_0/AMQMethodFactory_8_0.java diff --git a/gentools/src/org/apache/qpid/gentools/AmqpClass.java b/gentools/src/org/apache/qpid/gentools/AmqpClass.java index 2e8bdaf971..a93a636911 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpClass.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpClass.java @@ -20,129 +20,172 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; -public class AmqpClass implements Printable, NodeAware +import java.io.PrintStream; + +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/gentools/src/org/apache/qpid/gentools/AmqpConstant.java b/gentools/src/org/apache/qpid/gentools/AmqpConstant.java index 6ccd2dbf99..df5bc6c362 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpConstant.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpConstant.java @@ -25,151 +25,134 @@ import java.util.TreeMap; /** * @author kpvdr - * Class to represent the <constant> declaration within the AMQP specification. - * Currently, only integer values exist within the specification, however looking forward - * to other possible types in the future, string and double types are also supported. - * - * The <constant> declaration in the specification contains only two attributes: - * name and value. - * - * The value of the constant is mapped against the version(s) for which the name is defined. - * This allows for a change in the value rather than the name only from one version to the next. + * Class to represent the <constant> declaration within the AMQP specification. + * Currently, only integer values exist within the specification, however looking forward + * to other possible types in the future, string and double types are also supported. + *

+ * 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 + implements Printable, VersionConsistencyCheck, Comparable { /** * Constant name as defined by the name attribute of the <constant> declaration. */ - protected String name; - + private final String _name; + /** * Set of versions for which this constant name is defined. */ - protected AmqpVersionSet versionSet; + private final AmqpVersionSet _versionSet; /** * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. + * + * @param name Constant name as defined by the name attribute of the <constant> declaration. + * @param value Constant value as defined by the value attribute of the <constant> declaration. * @param version AMQP version for which this constant is defined */ - public AmqpConstant (String name, String value, AmqpVersion version) + public AmqpConstant(String name, String value, AmqpVersion version) { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); + _name = name; + _versionSet = new AmqpVersionSet(version); + AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); put(value, valueVersionSet); - } - - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, int value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(String.valueOf(value), valueVersionSet); } - /** - * Constructor - * @param name Constant name as defined by the name attribute of the <constant> declaration. - * @param value Constant value as defined by the value attribute of the <constant> declaration. - * @param version AMQP version for which this constant is defined - */ - public AmqpConstant (String name, double value, AmqpVersion version) - { - this.name = name; - versionSet = new AmqpVersionSet(version); - AmqpVersionSet valueVersionSet = new AmqpVersionSet(version); - put(String.valueOf(value), valueVersionSet); - } /** * Get the name of this constant. + * * @return Name of this constant, being the name attribute of the <constant> declaration - * represented by this class. + * represented by this class. */ public String getName() { - return name; + return _name; } - + /** * Get the value of this constant as a String. + * * @param version AMQP version for which this value is required. * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. + * represented by this class. * @throws AmqpTypeMappingException when a value is requested for a version for which it is not - * defined in the AMQP specifications. + * defined in the AMQP specifications. */ public String getStringValue(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { - for (String thisValue : keySet()) + for (String thisValue : keySet()) { AmqpVersionSet versionSet = get(thisValue); if (versionSet.contains(version)) + { return thisValue; + } } - throw new AmqpTypeMappingException("Unable to find value for constant \"" + name + - "\" for version " + version.toString() + "."); + throw new AmqpTypeMappingException("Unable to find value for constant \"" + getName() + + "\" for version " + version.toString() + "."); } - + /** * Get the value of this constant as an integer. + * * @param version AMQP version for which this value is required. * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. + * represented by this class. * @throws AmqpTypeMappingException when a value is requested for a version for which it is not - * defined in the AMQP specifications. + * defined in the AMQP specifications. */ public int getIntegerValue(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { return Integer.parseInt(getStringValue(version)); } - + /** * Get the value of this constant as a double. + * * @param version AMQP version for which this value is required. * @return Value of this constant, being the value attribute of the <constant> declaration - * represented by this class. + * represented by this class. * @throws AmqpTypeMappingException when a value is requested for a version for which it is not - * defined in the AMQP specifications. + * defined in the AMQP specifications. */ public double getDoubleValue(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { return Double.parseDouble(getStringValue(version)); } - + /** * Get the version set for this constant. It contains the all the versions for which this * constant name exists. + * * @return Set of versions for which this constant exists. */ public AmqpVersionSet getVersionSet() { - return versionSet; + return _versionSet; } - + /* (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(AmqpConstant other) { - int res = name.compareTo(other.name); + int res = getName().compareTo(other.getName()); if (res != 0) + { return res; - return versionSet.compareTo(other.versionSet); + } + return getVersionSet().compareTo(other.getVersionSet()); } /* (non-Javadoc) @@ -178,7 +161,9 @@ public class AmqpConstant extends TreeMap public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) { if (size() != 1) + { return false; + } return get(firstKey()).equals(globalVersionSet); } @@ -191,15 +176,16 @@ public class AmqpConstant extends TreeMap String tab = Utils.createSpaces(tabSize); if (size() == 1) { - out.println(margin + tab + "[C] " + name + " = \"" + firstKey() + "\" " + versionSet); + out.println(margin + tab + "[C] " + getName() + " = \"" + firstKey() + "\" " + getVersionSet()); } else { - out.println(margin + tab + "[C] " + name + ": " + versionSet); + out.println(margin + tab + "[C] " + getName() + ": " + getVersionSet()); for (String thisValue : keySet()) { - out.println(margin + tab + tab + "= \"" + thisValue + "\" " + get(thisValue)); + out.println(margin + tab + tab + "= \"" + thisValue + "\" " + get(thisValue)); } } } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java b/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java index 7b38f5cf3c..ab8b8be61e 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpConstantSet.java @@ -20,55 +20,58 @@ */ package org.apache.qpid.gentools; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + import java.io.PrintStream; import java.util.Iterator; import java.util.TreeSet; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - /** * @author kpvdr - * This class implements a set collection for {@link #AmqpConstant AmqpConstant} objects, being the collection - * of constants accumulated from various AMQP specification files processed. Each name occurs once only in the set. - * The {@link #AmqpConstant AmqpConstant} objects (derived from {@link java.util#TreeMap TreeMap}) keep track of - * the value and version(s) assigned to this name. + * This class implements a set collection for {@link AmqpConstant AmqpConstant} objects, being the collection + * of constants accumulated from various AMQP specification files processed. Each name occurs once only in the set. + * The {@link AmqpConstant AmqpConstant} objects (derived from {@link java.util.TreeMap TreeMap}) keep track of + * the value and version(s) assigned to this name. */ @SuppressWarnings("serial") -public class AmqpConstantSet extends TreeSet implements Printable, NodeAware, Comparable +public class AmqpConstantSet implements Printable, NodeAware //, Comparable { - public LanguageConverter converter; + private final LanguageConverter _converter; + private final TreeSet _constants = new TreeSet(); + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); public AmqpConstantSet(LanguageConverter converter) { - this.converter = converter; - this.converter.setConstantSet(this); + _converter = converter; + } - - /* (non-Javadoc) - * @see org.apache.qpid.gentools.NodeAware#addFromNode(org.w3c.dom.Node, int, org.apache.qpid.gentools.AmqpVersion) - */ + + /* (non-Javadoc) + * @see org.apache.qpid.gentools.NodeAware#addFromNode(org.w3c.dom.Node, int, org.apache.qpid.gentools.AmqpVersion) + */ public boolean addFromNode(Node node, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException + throws AmqpParseException, AmqpTypeMappingException { + _versionSet.add(version); NodeList nodeList = node.getChildNodes(); - for (int i=0; i cItr = iterator(); + Iterator cItr = _constants.iterator(); while (cItr.hasNext() && !foundName) { AmqpConstant thisConstant = cItr.next(); - if (name.compareTo(thisConstant.name) == 0) + if (name.compareTo(thisConstant.getName()) == 0) { foundName = true; - thisConstant.versionSet.add(version); + thisConstant.getVersionSet().add(version); // Now, find the value in the map boolean foundValue = false; for (String thisValue : thisConstant.keySet()) @@ -76,7 +79,7 @@ public class AmqpConstantSet extends TreeSet implements Printable, if (value.compareTo(thisValue) == 0) { foundValue = true; - // Add this version to existing version set. + // Add this version to existing version set. AmqpVersionSet versionSet = thisConstant.get(thisValue); versionSet.add(version); } @@ -85,49 +88,65 @@ public class AmqpConstantSet extends TreeSet implements Printable, if (!foundValue) { thisConstant.put(value, new AmqpVersionSet(version)); - } + } } } // Check that the name was found - if not, add it if (!foundName) { - add(new AmqpConstant(name, value, version)); + _constants.add(new AmqpConstant(name, value, version)); } - } + } } return true; } - + /* (non-Javadoc) - * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int) - */ + * @see org.apache.qpid.gentools.Printable#print(java.io.PrintStream, int, int) + */ public void print(PrintStream out, int marginSize, int tabSize) { out.println(Utils.createSpaces(marginSize) + "Constants: "); - for (AmqpConstant thisAmqpConstant : this) + for (AmqpConstant thisAmqpConstant : _constants) { - thisAmqpConstant.print(out, marginSize, tabSize); + thisAmqpConstant.print(out, marginSize, tabSize); } } - + /* (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public int compareTo(AmqpConstantSet other) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ +// public int compareTo(AmqpConstantSet other) +// { +// int res = size() - other.size(); +// if (res != 0) +// return res; +// Iterator 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; +// } + + public Iterable getContstants() { - 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; + return _constants; } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public LanguageConverter getConverter() + { + return _converter; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomain.java b/gentools/src/org/apache/qpid/gentools/AmqpDomain.java index 4796f31fb3..ba8552a6a6 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpDomain.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpDomain.java @@ -26,53 +26,64 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpDomain extends TreeMap implements Printable { - public String domainName; + private final String _domainName; - public AmqpDomain(String domainName) - { - this.domainName = domainName; - } + public AmqpDomain(String domainName) + { + _domainName = domainName; + } - public void addDomain(String domainType, AmqpVersion version) throws AmqpParseException - { - AmqpVersionSet versionSet = get(domainType); - if (versionSet == null) // First time, create new entry - { - versionSet = new AmqpVersionSet(); - put(domainType, versionSet); - } - versionSet.add(version); - } + public void addDomain(String domainType, AmqpVersion version) throws AmqpParseException + { + AmqpVersionSet versionSet = get(domainType); + if (versionSet == null) // First time, create new entry + { + versionSet = new AmqpVersionSet(); + put(domainType, versionSet); + } + versionSet.add(version); + } + + public String getDomainType(AmqpVersion version) + throws AmqpTypeMappingException + { + for (String thisDomainType : keySet()) + { + AmqpVersionSet versionSet = get(thisDomainType); + if (versionSet.contains(version)) + { + return thisDomainType; + } + } + throw new AmqpTypeMappingException("Unable to find version " + version + "."); + } + + public boolean hasVersion(String type, AmqpVersion v) + { + AmqpVersionSet vs = get(type); + if (vs == null) + { + return false; + } + return vs.contains(v); + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + String tab = Utils.createSpaces(tabSize); + out.println(margin + getDomainName() + ":"); + + for (String thisDomainType : keySet()) + { + AmqpVersionSet vs = get(thisDomainType); + out.println(margin + tab + thisDomainType + " : " + vs.toString()); + } + } + + public String getDomainName() + { + return _domainName; + } - public String getDomainType(AmqpVersion version) - throws AmqpTypeMappingException - { - for (String thisDomainType : keySet()) - { - AmqpVersionSet versionSet = get(thisDomainType); - if (versionSet.contains(version)) - return thisDomainType; - } throw new AmqpTypeMappingException("Unable to find version " + version + "."); - } - - public boolean hasVersion(String type, AmqpVersion v) - { - AmqpVersionSet vs = get(type); - if (vs == null) - return false; - return vs.contains(v); - } - - public void print(PrintStream out, int marginSize, int tabSize) - { - String margin = Utils.createSpaces(marginSize); - String tab = Utils.createSpaces(tabSize); - out.println(margin + domainName + ":"); - - for (String thisDomainType : keySet()) - { - AmqpVersionSet vs = get(thisDomainType); - out.println(margin + tab + thisDomainType + " : " + vs.toString()); - } - } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java b/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java index 7e2974a444..0cd9d214bd 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpDomainMap.java @@ -20,100 +20,109 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; -import java.util.TreeMap; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.TreeMap; + @SuppressWarnings("serial") public class AmqpDomainMap extends TreeMap implements Printable, NodeAware { - public LanguageConverter converter; + private final LanguageConverter _converter; - public AmqpDomainMap(LanguageConverter converter) - { - this.converter = converter; - this.converter.setDomainMap(this); - } - - public boolean addFromNode(Node n, int o, AmqpVersion v) - throws AmqpParseException, AmqpTypeMappingException - { - NodeList nl = n.getChildNodes(); - for (int i=0; i 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 AmqpDomainMap(LanguageConverter converter) + { + _converter = converter; - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - AmqpDomain domainType = get(domainName); - // For AMQP 8.0, primitive types were not described as domains, so - // return itself as the type. - if (domainType == null) - { - return domainName; - } - try - { - return domainType.getDomainType(version); - } - catch (AmqpTypeMappingException e) - { - throw new AmqpTypeMappingException("Unable to find domain type for domain \"" + domainName + - "\" version " + version + "."); - } - } - - - public void print(PrintStream out, int marginSize, int tabSize) - { + } + + public boolean addFromNode(Node n, int o, AmqpVersion v) + throws AmqpParseException, AmqpTypeMappingException + { + NodeList nl = n.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) + { + Node c = nl.item(i); + // All versions 0.9 and greater use for all domains + if (c.getNodeName().compareTo(Utils.ELEMENT_DOMAIN) == 0) + { + String domainName = getConverter().prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); + String type = Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE); + AmqpDomain thisDomain = get(domainName); + if (thisDomain == null) + { + thisDomain = new AmqpDomain(domainName); + put(domainName, thisDomain); + } + thisDomain.addDomain(type, v); + } + // Version(s) 0.8 and earlier use 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 = getConverter().prepareDomainName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_TYPE)); + AmqpDomain thisDomain = get(type); + if (thisDomain == null) + { + thisDomain = new AmqpDomain(type); + put(type, thisDomain); + } + if (!thisDomain.hasVersion(type, v)) + { + thisDomain.addDomain(type, v); + } + } + catch (AmqpParseException e) + { + } // Ignore fields without type attribute + } + else if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0 || + c.getNodeName().compareTo(Utils.ELEMENT_METHOD) == 0) + { + addFromNode(c, 0, v); + } + } + return true; + } + + public String getDomainType(String domainName, AmqpVersion version) + { + AmqpDomain domainType = get(domainName); + // For AMQP 8.0, primitive types were not described as domains, so + // return itself as the type. + if (domainType == null) + { + return domainName; + } + try + { + return domainType.getDomainType(version); + } + catch (AmqpTypeMappingException e) + { + throw new AmqpTypeMappingException("Unable to find domain type for domain \"" + domainName + + "\" version " + version + "."); + } + } + + + public void print(PrintStream out, int marginSize, int tabSize) + { out.println(Utils.createSpaces(marginSize) + "Domain Map:"); for (String thisDomainName : keySet()) - { - AmqpDomain domain = get(thisDomainName); - domain.print(out, marginSize + tabSize, tabSize); - } - } + { + AmqpDomain domain = get(thisDomainName); + domain.print(out, marginSize + tabSize, tabSize); + } + } + + public LanguageConverter getConverter() + { + return _converter; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java b/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java index f91d98bfe7..e39550b96f 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpDomainVersionMap.java @@ -25,34 +25,38 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpDomainVersionMap extends TreeMap 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; - } +{ + 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/gentools/src/org/apache/qpid/gentools/AmqpField.java b/gentools/src/org/apache/qpid/gentools/AmqpField.java index e1177e0154..32f87fafa3 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpField.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpField.java @@ -20,137 +20,231 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; -import java.util.ArrayList; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + public class AmqpField implements Printable, NodeAware, VersionConsistencyCheck { - public LanguageConverter converter; - public AmqpVersionSet versionSet; - public AmqpDomainVersionMap domainMap; - public AmqpOrdinalVersionMap ordinalMap; - public String name; - - public AmqpField(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - domainMap = new AmqpDomainVersionMap(); - ordinalMap = new AmqpOrdinalVersionMap(); - } - - public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - String domainType; - // Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields. - try - { - domainType = converter.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN)); - } - catch (AmqpParseException e) - { - domainType = converter.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE)); - } - AmqpVersionSet thisVersionList = domainMap.get(domainType); - if (thisVersionList == null) // First time, create new entry - { - thisVersionList = new AmqpVersionSet(); - domainMap.put(domainType, thisVersionList); - } - thisVersionList.add(version); - thisVersionList = ordinalMap.get(ordinal); - if (thisVersionList == null) // First time, create new entry - { - thisVersionList = new AmqpVersionSet(); - ordinalMap.put(ordinal, thisVersionList); - } - thisVersionList.add(version); - NodeList nList = fieldNode.getChildNodes(); - for (int i=0; i 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; - } + + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + private final AmqpDomainVersionMap _domainMap = new AmqpDomainVersionMap(); + private final AmqpOrdinalVersionMap _ordinalMap = new AmqpOrdinalVersionMap(); + + private final String _name; + private final Generator _generator; + + private final Map _versionToDomainMap = new HashMap(); + private final Map _versionToOrdinalMap = new HashMap(); + + + public AmqpField(String name, Generator generator) + { + _name = name; + _generator = generator; + + } + + public boolean addFromNode(Node fieldNode, int ordinal, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + _versionSet.add(version); + String domainType; + // Early versions of the spec (8.0) used the "type" attribute instead of "domain" for some fields. + try + { + domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_DOMAIN)); + } + catch (AmqpParseException e) + { + domainType = _generator.prepareDomainName(Utils.getNamedAttribute(fieldNode, Utils.ATTRIBUTE_TYPE)); + } + AmqpVersionSet thisVersionList = _domainMap.get(domainType); + if (thisVersionList == null) // First time, create new entry + { + thisVersionList = new AmqpVersionSet(); + _domainMap.put(domainType, thisVersionList); + } + + _versionToDomainMap.put(version, domainType); + _versionToOrdinalMap.put(version, ordinal); + + thisVersionList.add(version); + thisVersionList = _ordinalMap.get(ordinal); + if (thisVersionList == null) // First time, create new entry + { + thisVersionList = new AmqpVersionSet(); + _ordinalMap.put(ordinal, thisVersionList); + } + thisVersionList.add(version); + NodeList nList = fieldNode.getChildNodes(); + for (int i = 0; i < nList.getLength(); i++) + { + Node child = nList.item(i); + if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) + { + String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); + if (value.compareTo("no-gen") == 0) + { + return false; + } + } + } + return true; + } + + public void removeVersion(AmqpVersion version) + { + _domainMap.removeVersion(version); + _ordinalMap.removeVersion(version); + _versionSet.remove(version); + } + + public boolean isCodeTypeConsistent(LanguageConverter converter) + throws AmqpTypeMappingException + { + if (_domainMap.size() == 1) + { + return true; // By definition + } + ArrayList 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.getVersionSet().size(); + } + + public boolean isTypeAndNameConsistent(Generator generator) + throws AmqpTypeMappingException + { + if (!isCodeTypeConsistent(generator)) + { + return false; + } + // Since the various doamin names map to the same code type, add the version occurrences + // across all domains to see we have all possible versions covered + int vCntr = 0; + for (String thisDomainName : _domainMap.keySet()) + { + vCntr += _domainMap.get(thisDomainName).size(); + } + return vCntr == getVersionSet().size(); + } + + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + out.println(margin + "[F] " + _name + ": " + _versionSet); + + for (Integer thisOrdinal : _ordinalMap.keySet()) + { + AmqpVersionSet versionList = _ordinalMap.get(thisOrdinal); + out.println(margin + " [O] " + thisOrdinal + " : " + versionList.toString()); + } + + for (String thisDomainName : _domainMap.keySet()) + { + AmqpVersionSet versionList = _domainMap.get(thisDomainName); + out.println(margin + " [D] " + thisDomainName + " : " + versionList.toString()); + } + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (!_versionSet.equals(globalVersionSet)) + { + return false; + } + if (!_domainMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_ordinalMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + return true; + } + + public String getDomain(AmqpVersion version) + { + return _versionToDomainMap.get(version); + } + + public String getConsistentNativeType() + { + return _generator.getNativeType(_generator.getDomainType(getDomain(_versionSet.first()),_versionSet.first())); + } + + public int getOrdinal(AmqpVersion version) + { + return _versionToOrdinalMap.get(version); + } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public AmqpDomainVersionMap getDomainMap() + { + return _domainMap; + } + + public AmqpOrdinalVersionMap getOrdinalMap() + { + return _ordinalMap; + } + + public String getName() + { + return _name; + } + + public LanguageConverter getGenerator() + { + return _generator; + } + + public Map getVersionToDomainMap() + { + return _versionToDomainMap; + } + + public Map getVersionToOrdinalMap() + { + return _versionToOrdinalMap; + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java b/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java index c91ec3d623..41e62bdad9 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpFieldMap.java @@ -20,329 +20,419 @@ */ package org.apache.qpid.gentools; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import java.util.TreeMap; @SuppressWarnings("serial") -public class AmqpFieldMap extends TreeMap implements VersionConsistencyCheck +public class AmqpFieldMap implements VersionConsistencyCheck { - public void removeVersion(AmqpVersion version) - { - String[] fieldNameArray = new String[size()]; - keySet().toArray(fieldNameArray); - for (String fieldName : fieldNameArray) - { - get(fieldName).removeVersion(version); - remove(fieldName); - } - } - - public AmqpFieldMap getFieldMapForOrdinal(int ordinal) - { - AmqpFieldMap newMap = new AmqpFieldMap(); - for (String thisFieldName: keySet()) - { - AmqpField field = get(thisFieldName); - TreeMap 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; - } + + private final TreeMap _map = new TreeMap(); + + private final AmqpVersionSet _versionSet = new AmqpVersionSet(); + + public void removeVersion(AmqpVersion version) + { + String[] fieldNameArray = new String[size()]; + _map.keySet().toArray(fieldNameArray); + Iterator> iter = _map.entrySet().iterator(); + + while (iter.hasNext()) + { + Entry entry = iter.next(); + entry.getValue().removeVersion(version); + iter.remove(); + } + } + + public int size() + { + return _map.size(); + + } + + public AmqpFieldMap getFieldMapForOrdinal(int ordinal) + { + AmqpFieldMap newMap = new AmqpFieldMap(); + for (AmqpField field : _map.values()) + { + + TreeMap ordinalMap = field.getOrdinalMap(); + AmqpVersionSet ordinalVersions = ordinalMap.get(ordinal); + if (ordinalVersions != null) + { + newMap.add(field.getName(), field); + } + } + return newMap; + } + + public void add(String name, AmqpField field) + { + _versionSet.addAll(field.getVersionSet()); + _map.put(name, field); + } + + public AmqpOrdinalFieldMap getMapForVersion(AmqpVersion version, boolean codeTypeFlag, + LanguageConverter converter) + { + // TODO: REVIEW THIS! There may be a bug here that affects C++ generation (only with >1 version)... + // If version == null (a common scenario) then the version map is built up on the + // basis of first found item, and ignores other version variations. + // This should probably be disallowed by throwing an NPE, as AmqpOrdinalFieldMap cannot + // represent these possibilities. + // *OR* + // Change the structure of AmqpOrdianlFieldMap to allow for the various combinations that + // will result from version variation - but that is what AmqpFieldMap is... :-$ + AmqpOrdinalFieldMap ordinalFieldMap = new AmqpOrdinalFieldMap(); + for (AmqpField field : _map.values()) + { + + if (version == null || field.getVersionSet().contains(version)) + { + // 1. Search for domain name in field domain map with version that matches + String domain = ""; + boolean dFound = false; + for (String thisDomainName : field.getDomainMap().keySet()) + { + domain = thisDomainName; + AmqpVersionSet versionSet = field.getDomainMap().get(domain); + if (version == null || versionSet.contains(version)) + { + if (codeTypeFlag) + { + domain = converter.getGeneratedType(domain, version); + } + dFound = true; + } + } + + // 2. Search for ordinal in field ordianl map with version that matches + int ordinal = -1; + boolean oFound = false; + for (Integer thisOrdinal : field.getOrdinalMap().keySet()) + { + ordinal = thisOrdinal; + AmqpVersionSet versionSet = field.getOrdinalMap().get(ordinal); + if (version == null || versionSet.contains(version)) + { + oFound = true; + } + } + + if (dFound && oFound) + { + String[] fieldDomainPair = {field.getName(), domain}; + ordinalFieldMap.put(ordinal, fieldDomainPair); + } + } + } + return ordinalFieldMap; + } + + public boolean isDomainConsistent(Generator generator, AmqpVersionSet versionSet) + throws AmqpTypeMappingException + { + if (size() != 1) // Only one field for this ordinal + { + return false; + } + return _map.get(_map.firstKey()).isConsistent(generator); + } + + public int getNumFields(AmqpVersion version) + { + int fCntr = 0; + for (AmqpField field : _map.values()) + { + + if (field.getVersionSet().contains(version)) + { + fCntr++; + } + } + return fCntr; + } + + public String parseFieldMap(CommandGenerateMethod commonGenerateMethod, MangledGenerateMethod mangledGenerateMethod, + int indentSize, int tabSize, LanguageConverter converter) + { + String indent = Utils.createSpaces(indentSize); + String cr = Utils.LINE_SEPARATOR; + StringBuffer sb = new StringBuffer(); + + if (commonGenerateMethod == null) + { + // Generate warnings in code if required methods are null. + sb.append(indent + "/*********************************************************" + cr); + sb.append(indent + " * WARNING: Generated code could be missing." + cr); + sb.append(indent + " * In call to parseFieldMap(), generation method was null." + cr); + sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); + sb.append(indent + " *********************************************************/" + cr); + } + + Iterator> itr = _map.entrySet().iterator(); + while (itr.hasNext()) + { + Entry entry = itr.next(); + String fieldName = entry.getKey(); + AmqpField field = entry.getValue(); + if (field.isCodeTypeConsistent(converter)) + { + // All versions identical - Common declaration + String domainName = field.getDomainMap().firstKey(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = converter.getGeneratedType(domainName, versionSet.first()); + if (commonGenerateMethod != null) + { + sb.append(commonGenerateMethod.generate(codeType, field, versionSet, + indentSize, tabSize, itr.hasNext())); + } + } + else if (mangledGenerateMethod != null) // Version-mangled + { + sb.append(mangledGenerateMethod.generate(field, indentSize, tabSize, + itr.hasNext())); + } + } + return sb.toString(); + } + + public String parseFieldMapOrdinally(GenerateMethod generateMethod, BitFieldGenerateMethod bitGenerateMethod, + int indentSize, int tabSize, Generator codeGenerator) + { + String indent = Utils.createSpaces(indentSize); + String cr = Utils.LINE_SEPARATOR; + StringBuffer sb = new StringBuffer(); + + // Generate warnings in code if required methods are null. + if (generateMethod == null || bitGenerateMethod == null) + { + sb.append(indent + "/***********************************************" + cr); + sb.append(indent + " * WARNING: In call to parseFieldMapOrdinally():" + cr); + if (generateMethod == null) + { + sb.append(indent + " * => generateMethod is null." + cr); + } + if (bitGenerateMethod == null) + { + sb.append(indent + " * => bitGenerateMethod is null." + cr); + } + sb.append(indent + " * Generated code could be missing." + cr); + sb.append(indent + " * Check for NoSuchMethodException on startup." + cr); + sb.append(indent + " ***********************************************/" + cr); + } + + /* We must process elements in ordinal order because adjacent booleans (bits) + * must be combined into a single byte (in groups of up to 8). Start with shared + * declarations until an ordinal divergence is found. (For most methods where + * there is no difference between versions, this will simplify the generated + * code. */ + + ArrayList 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, getVersionSet())) + { + String fieldName = ordinalFieldMap.getFirstFieldName(); + String domain = ordinalFieldMap._map.get(fieldName).getDomainMap().firstKey(); + + String domainType = codeGenerator.getDomainType(domain, + codeGenerator.getVersionSet().first()); + + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldName); + } + else if (bitFieldList.size() > 0) + { + // End of bit types - handle deferred bit type generation + if (bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate(bitFieldList, ordinal, + indentSize, tabSize)); + } + bitFieldList.clear(); + } + if (!ordinalDivergenceFlag) + { + // Defer generation of bit types until all adjacent bits have been + // accounted for. + if (bitFieldList.size() == 0 && generateMethod != null) + { + sb.append(generateMethod.generate(domainType, fieldName, ordinal, + indentSize, tabSize)); + } + } + ordinal++; + } + else + { + ordinalDivergenceFlag = true; + } + } + } + + // Check if there is still more to do under a version-specific breakout + if (ordinalDivergenceFlag && ordinal < size()) + { + // 1. Cycle through all versions in order, create outer if(version) structure + AmqpVersion[] versionArray = new AmqpVersion[getVersionSet().size()]; + getVersionSet().toArray(versionArray); + for (int v = 0; v < versionArray.length; v++) + { + sb.append(indent); + if (v > 0) + { + sb.append("else "); + } + sb.append("if (major == " + versionArray[v].getMajor() + " && minor == " + + versionArray[v].getMinor() + ")" + cr); + sb.append(indent + "{" + cr); + + // 2. Cycle though each ordinal from where we left off in the loop above. + ArrayList bitFieldList2 = new ArrayList(bitFieldList); + for (int o = ordinal; o < size(); o++) + { + AmqpFieldMap ordinalFieldMap = getFieldMapForOrdinal(o); + if (ordinalFieldMap.size() > 0) + { + // 3. Cycle through each of the fields that have this ordinal. + Iterator> i = ordinalFieldMap._map.entrySet().iterator(); + while (i.hasNext()) + { + + Map.Entry entry = i.next(); + AmqpField field = entry.getValue(); + String fieldName = entry.getKey(); + + // 4. Some fields may have more than one ordinal - match by both + // ordinal and version. + Iterator j = field.getOrdinalMap().keySet().iterator(); + while (j.hasNext()) + { + int thisOrdinal = j.next(); + AmqpVersionSet v1 = field.getOrdinalMap().get(thisOrdinal); + if (thisOrdinal == o && v1.contains(versionArray[v])) + { + // 5. Now get the domain for this version + int domainCntr = 0; + Iterator k = field.getDomainMap().keySet().iterator(); + while (k.hasNext()) + { + // Mangle domain-divergent field names + String mangledFieldName = fieldName; + if (field.getDomainMap().size() > 1) + { + mangledFieldName += "_" + (domainCntr++); + } + String domainName = k.next(); + AmqpVersionSet v2 = field.getDomainMap().get(domainName); + if (v2.contains(versionArray[v])) + { + // 6. (Finally!!) write the declaration + String domainType = codeGenerator.getDomainType(domainName, + versionArray[v]); + if (domainType.compareTo("bit") == 0) + { + bitFieldList2.add(mangledFieldName); + } + else if (bitFieldList2.size() > 0) + { + // End of bit types - handle deferred bit type generation + if (bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate( + bitFieldList2, o, indentSize + tabSize, + tabSize)); + } + bitFieldList2.clear(); + } + // Defer generation of bit types until all adjacent bits have + // been accounted for. + if (bitFieldList2.size() == 0 && generateMethod != null) + { + sb.append(generateMethod.generate(domainType, + mangledFieldName, o, indentSize + tabSize, tabSize)); + } + } + } + } + } + } + } + } + // Check for remaining deferred bits + if (bitFieldList2.size() > 0 && bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate(bitFieldList2, size(), + indentSize + tabSize, tabSize)); + } + sb.append(indent + "}" + cr); + } + } + // Check for remaining deferred bits + else if (bitFieldList.size() > 0 && bitGenerateMethod != null) + { + sb.append(bitGenerateMethod.generate(bitFieldList, size(), + indentSize, tabSize)); + } + return sb.toString(); + } + + private String getFirstFieldName() + { + return _map.firstKey(); + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + for (String thisFieldName : _map.keySet()) + { + AmqpField field = _map.get(thisFieldName); + if (!field.isVersionConsistent(globalVersionSet)) + { + return false; + } + } + return true; + } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public Collection values() + { + return _map.values(); + } + + public AmqpField get(String fieldName) + { + return _map.get(fieldName); + } + + public void remove(String fieldName) + { + _map.remove(fieldName); + } + + public Set keySet() + { + return _map.keySet(); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java b/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java index 048221bda8..5993a1b715 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpFlagMap.java @@ -26,46 +26,52 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpFlagMap extends TreeMap implements VersionConsistencyCheck { - public boolean isSet() - { - return containsKey(true); - } - - public String toString() - { - AmqpVersionSet versionSet = get(true); - if (versionSet != null) - return versionSet.toString(); - return ""; - } - - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (size() != 1) - return false; - return get(firstKey()).equals(globalVersionSet); - } - - public boolean removeVersion(AmqpVersion version) - { - Boolean res = false; - ArrayList 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; - } + public boolean isSet() + { + return containsKey(true); + } + + public String toString() + { + AmqpVersionSet versionSet = get(true); + if (versionSet != null) + { + return versionSet.toString(); + } + return ""; + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + { + return false; + } + return get(firstKey()).equals(globalVersionSet); + } + + public boolean removeVersion(AmqpVersion version) + { + Boolean res = false; + ArrayList 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/gentools/src/org/apache/qpid/gentools/AmqpMethod.java b/gentools/src/org/apache/qpid/gentools/AmqpMethod.java index ce963465de..eb81e18d66 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpMethod.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpMethod.java @@ -20,183 +20,279 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Collection; + public class 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 AmqpMethod(String name, LanguageConverter converter) - { - this.name = name; - this.converter = converter; - versionSet = new AmqpVersionSet(); - fieldMap = new AmqpFieldMap(); - indexMap = new AmqpOrdinalVersionMap(); - clientMethodFlagMap = new AmqpFlagMap(); - serverMethodFlagMap = new AmqpFlagMap(); - } - - public boolean addFromNode(Node methodNode, int ordinal, AmqpVersion version) - throws AmqpParseException, AmqpTypeMappingException - { - versionSet.add(version); - boolean serverChassisFlag = false; - boolean clientChassisFlag = false; - int index = Utils.getNamedIntegerAttribute(methodNode, "index"); - AmqpVersionSet indexVersionSet = indexMap.get(index); - if (indexVersionSet != null) - indexVersionSet.add(version); - else - { - indexVersionSet = new AmqpVersionSet(); - indexVersionSet.add(version); - indexMap.put(index, indexVersionSet); - } - NodeList nList = methodNode.getChildNodes(); - int fieldCntr = fieldMap.size(); - for (int i=0; i in XML) + private final AmqpFlagMap _serverMethodFlagMap = new AmqpFlagMap(); // Method called on server ( in XML) + + private final Map _versionToFieldsMap = new HashMap(); + + private final String _name; + private final Generator _generator; + + + public AmqpMethod(String name, Generator generator) + { + _name = name; + _generator = generator; + } + + public boolean addFromNode(Node methodNode, int ordinal, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + _versionSet.add(version); + boolean serverChassisFlag = false; + boolean clientChassisFlag = false; + int index = Utils.getNamedIntegerAttribute(methodNode, "index"); + AmqpVersionSet indexVersionSet = _indexMap.get(index); + if (indexVersionSet != null) + { + indexVersionSet.add(version); + } + else + { + indexVersionSet = new AmqpVersionSet(); + indexVersionSet.add(version); + _indexMap.put(index, indexVersionSet); + } + NodeList nList = methodNode.getChildNodes(); + int fieldCntr = _fieldMap.size(); + for (int i = 0; i < nList.getLength(); i++) + { + Node child = nList.item(i); + if (child.getNodeName().compareTo(Utils.ELEMENT_FIELD) == 0) + { + String fieldName = _generator.prepareDomainName(Utils.getNamedAttribute(child, + Utils.ATTRIBUTE_NAME)); + AmqpField thisField = _fieldMap.get(fieldName); + AmqpFieldMap versionSpecificFieldMap = _versionToFieldsMap.get(version); + if (versionSpecificFieldMap == null) + { + versionSpecificFieldMap = new AmqpFieldMap(); + _versionToFieldsMap.put(version, versionSpecificFieldMap); + } + + + if (thisField == null) + { + thisField = new AmqpField(fieldName, _generator); + _fieldMap.add(fieldName, thisField); + } + + AmqpField versionSpecificField = new AmqpField(fieldName, _generator); + versionSpecificFieldMap.add(fieldName, versionSpecificField); + + versionSpecificField.addFromNode(child, fieldCntr, version); + + if (!thisField.addFromNode(child, fieldCntr++, version)) + { + String className = _generator.prepareClassName(Utils.getNamedAttribute(methodNode.getParentNode(), + Utils.ATTRIBUTE_NAME)); + String methodName = _generator.prepareMethodName(Utils.getNamedAttribute(methodNode, + Utils.ATTRIBUTE_NAME)); + System.out.println("INFO: Generation supression tag found for field " + + className + "." + methodName + "." + fieldName + " - removing."); + thisField.removeVersion(version); + _fieldMap.remove(fieldName); + } + } + else if (child.getNodeName().compareTo(Utils.ELEMENT_CHASSIS) == 0) + { + String chassisName = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_NAME); + if (chassisName.compareTo("server") == 0) + { + serverChassisFlag = true; + } + else if (chassisName.compareTo("client") == 0) + { + clientChassisFlag = true; + } + } + else if (child.getNodeName().compareTo(Utils.ELEMENT_CODEGEN) == 0) + { + String value = Utils.getNamedAttribute(child, Utils.ATTRIBUTE_VALUE); + if (value.compareTo("no-gen") == 0) + { + return false; + } + } + } + processChassisFlags(serverChassisFlag, clientChassisFlag, version); + return true; + } + + public void removeVersion(AmqpVersion version) + { + _clientMethodFlagMap.removeVersion(version); + _serverMethodFlagMap.removeVersion(version); + _indexMap.removeVersion(version); + _fieldMap.removeVersion(version); + _versionSet.remove(version); + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + String margin = Utils.createSpaces(marginSize); + String tab = Utils.createSpaces(tabSize); + out.println(margin + "[M] " + _name + " {" + (_serverMethodFlagMap.isSet() ? "S " + + _serverMethodFlagMap + ( + _clientMethodFlagMap.isSet() ? ", " : "") : "") + + (_clientMethodFlagMap.isSet() + ? "C " + _clientMethodFlagMap : "") + "}" + ": " + + _versionSet); + + for (Integer thisIndex : _indexMap.keySet()) + { + AmqpVersionSet indexVersionSet = _indexMap.get(thisIndex); + out.println(margin + tab + "[I] " + thisIndex + indexVersionSet); + } + + for (String thisFieldName : _fieldMap.keySet()) + { + AmqpField thisField = _fieldMap.get(thisFieldName); + thisField.print(out, marginSize + tabSize, tabSize); + } + } + + protected void processChassisFlags(boolean serverFlag, boolean clientFlag, AmqpVersion version) + { + AmqpVersionSet versionSet = _serverMethodFlagMap.get(serverFlag); + if (versionSet != null) + { + versionSet.add(version); + } + else + { + versionSet = new AmqpVersionSet(); + versionSet.add(version); + _serverMethodFlagMap.put(serverFlag, versionSet); + } + + versionSet = _clientMethodFlagMap.get(clientFlag); + if (versionSet != null) + { + versionSet.add(version); + } + else + { + versionSet = new AmqpVersionSet(); + versionSet.add(version); + _clientMethodFlagMap.put(clientFlag, versionSet); + } + } + + public AmqpOverloadedParameterMap getOverloadedParameterLists(AmqpVersionSet globalVersionSet, + Generator generator) + throws AmqpTypeMappingException + { + AmqpOverloadedParameterMap parameterVersionMap = new AmqpOverloadedParameterMap(); + for (AmqpVersion thisVersion : globalVersionSet) + { + AmqpOrdinalFieldMap ordinalFieldMap = _fieldMap.getMapForVersion(thisVersion, true, generator); + AmqpVersionSet methodVersionSet = parameterVersionMap.get(ordinalFieldMap); + if (methodVersionSet == null) + { + methodVersionSet = new AmqpVersionSet(); + methodVersionSet.add(thisVersion); + parameterVersionMap.put(ordinalFieldMap, methodVersionSet); + } + else + { + methodVersionSet.add(thisVersion); + } + } + return parameterVersionMap; + } + + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (!_versionSet.equals(globalVersionSet)) + { + return false; + } + if (!_clientMethodFlagMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_serverMethodFlagMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_indexMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + if (!_fieldMap.isVersionConsistent(globalVersionSet)) + { + return false; + } + return true; + } + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public AmqpFieldMap getFieldMap() + { + return _fieldMap; + } + + public AmqpOrdinalVersionMap getIndexMap() + { + return _indexMap; + } + + public AmqpFlagMap getClientMethodFlagMap() + { + return _clientMethodFlagMap; + } + + public AmqpFlagMap getServerMethodFlagMap() + { + return _serverMethodFlagMap; + } + + public Map getVersionToFieldsMap() + { + return _versionToFieldsMap; + } + + public String getName() + { + return _name; + } + + public LanguageConverter getGenerator() + { + return _generator; + } + + public SingleVersionMethod asSingleVersionMethod(AmqpVersion version) + { + return new SingleVersionMethod(this, version, _generator); + } + + public Collection getFields() + { + return _fieldMap.values(); + } + + public boolean isCommon(AmqpField field) + { + return field.getVersionSet().equals(getVersionSet()) && field.isTypeAndNameConsistent(_generator); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java b/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java index 59eedd2a2b..d98dab4a39 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpMethodMap.java @@ -25,12 +25,12 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpMethodMap extends TreeMap { - public void removeVersion(AmqpVersion version) - { - for (String methodName : keySet()) - { - get(methodName).removeVersion(version); - } - } + public void removeVersion(AmqpVersion version) + { + for (String methodName : keySet()) + { + get(methodName).removeVersion(version); + } + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpModel.java b/gentools/src/org/apache/qpid/gentools/AmqpModel.java index 721247a4b2..447bca6c4f 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpModel.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpModel.java @@ -20,61 +20,106 @@ */ package org.apache.qpid.gentools; -import java.io.PrintStream; - import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.Map; + 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 _versionToClassMapMap = new HashMap(); + + public AmqpModel(Generator generator) + { + _generator = generator; + } + + public AmqpClassMap getAmqpClassMap(AmqpVersion version) + { + return _versionToClassMapMap.get(version); + } + + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + public boolean addFromNode(Node n, int o, AmqpVersion version) + throws AmqpParseException, AmqpTypeMappingException + { + _versionSet.add(version); + NodeList nList = n.getChildNodes(); + + AmqpClassMap versionSpecificClassMap = _versionToClassMapMap.get(version); + + if (versionSpecificClassMap == null) + { + versionSpecificClassMap = new AmqpClassMap(); + _versionToClassMapMap.put(version, versionSpecificClassMap); + } + + int eCntr = 0; + for (int i = 0; i < nList.getLength(); i++) + { + Node c = nList.item(i); + if (c.getNodeName().compareTo(Utils.ELEMENT_CLASS) == 0) + { + String className = _generator.prepareClassName(Utils.getNamedAttribute(c, Utils.ATTRIBUTE_NAME)); + AmqpClass thisClass = classMap.get(className); + if (thisClass == null) + { + thisClass = new AmqpClass(className, _generator); + classMap.put(className, thisClass); + } + + AmqpClass versionSpecificClass = new AmqpClass(className, _generator); + versionSpecificClassMap.put(className, versionSpecificClass); + + versionSpecificClass.addFromNode(c, eCntr, version); + + if (!thisClass.addFromNode(c, eCntr++, version)) + { + System.out.println("INFO: Generation supression tag found for class " + className + " - removing."); + thisClass.removeVersion(version); + classMap.remove(className); + } + } + } + return true; + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + out.println(Utils.createSpaces(marginSize) + + "[C]=class; [M]=method; [F]=field; [D]=domain; [I]=index; [O]=ordinal" + Utils.LINE_SEPARATOR); + out.println(Utils.createSpaces(marginSize) + "Model:"); + + for (String thisClassName : classMap.keySet()) + { + AmqpClass thisClass = classMap.get(thisClassName); + thisClass.print(out, marginSize + tabSize, tabSize); + } + } + + public LanguageConverter getGenerator() + { + return _generator; + } + + public AmqpClassMap getClassMap() + { + return classMap; + } + + public SingleVersionModel asSingleVersionModel() + { + return new SingleVersionModel(this, getVersionSet().first(), _generator); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java index 34d3b7ca5f..0633eff1e1 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalFieldMap.java @@ -27,63 +27,70 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpOrdinalFieldMap extends TreeMap 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 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 < thisPair.length; i++) + { + int diff = thisPair[i].compareTo(oPair[i]); + if (diff != 0) + { + return diff; + } + } + } + return 0; + } + + public String toString() + { + StringBuffer sb = new StringBuffer(); + for (Integer thisOrdinal : keySet()) + { + String[] pair = get(thisOrdinal); + sb.append("[" + thisOrdinal + "] " + pair[0] + " : " + pair[1] + Utils.LINE_SEPARATOR); + } + return sb.toString(); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java index 3706c9391d..fede88631a 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpOrdinalVersionMap.java @@ -26,47 +26,51 @@ import java.util.TreeMap; @SuppressWarnings("serial") public class AmqpOrdinalVersionMap extends TreeMap implements VersionConsistencyCheck { - public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) - { - if (size() != 1) - return false; - return get(firstKey()).equals(globalVersionSet); - } - + public boolean isVersionConsistent(AmqpVersionSet globalVersionSet) + { + if (size() != 1) + { + return false; + } + return get(firstKey()).equals(globalVersionSet); + } + public int getOrdinal(AmqpVersion version) - throws AmqpTypeMappingException + throws AmqpTypeMappingException { - for (Integer thisOrdinal : keySet()) + for (Integer thisOrdinal : keySet()) { AmqpVersionSet versionSet = get(thisOrdinal); if (versionSet.contains(version)) + { return thisOrdinal; + } } throw new AmqpTypeMappingException("Unable to locate version " + version + " in ordianl version map."); } - - public boolean removeVersion(AmqpVersion version) - { - Boolean res = false; - ArrayList 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; - } + + 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/gentools/src/org/apache/qpid/gentools/AmqpParseException.java b/gentools/src/org/apache/qpid/gentools/AmqpParseException.java index 4d9f495390..3f3d4611fc 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpParseException.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpParseException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class AmqpParseException extends Exception +public class AmqpParseException extends RuntimeException { - public AmqpParseException(String msg) - { - super(msg); - } + public AmqpParseException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java b/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java index b1e6f3d712..1ac09ea453 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpTemplateException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class AmqpTemplateException extends Exception +public class AmqpTemplateException extends RuntimeException { - public AmqpTemplateException(String msg) - { - super(msg); - } + public AmqpTemplateException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java b/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java index 1053543fdd..127a8835b0 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpTypeMappingException.java @@ -21,10 +21,10 @@ package org.apache.qpid.gentools; @SuppressWarnings("serial") -public class AmqpTypeMappingException extends Exception +public class AmqpTypeMappingException extends RuntimeException { - public AmqpTypeMappingException(String msg) - { - super(msg); - } + public AmqpTypeMappingException(String msg) + { + super(msg); + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpVersion.java b/gentools/src/org/apache/qpid/gentools/AmqpVersion.java index 579d8e28b2..dbeef1b895 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpVersion.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpVersion.java @@ -22,47 +22,51 @@ package org.apache.qpid.gentools; public class AmqpVersion implements Comparable { - private int major; - private int minor; - - public AmqpVersion(int major, int minor) - { - this.major = major; - this.minor = minor; - } + private final int _major; + private final int _minor; - public AmqpVersion(AmqpVersion version) - { - this.major = version.major; - this.minor = version.minor; - } - - public int getMajor() - { - return major; - } - - public int getMinor() - { - return minor; - } - - public int compareTo(AmqpVersion v) - { - if (major != v.major) - return major - v.major; - if (minor != v.minor) - return minor - v.minor; - return 0; - } - - public String namespace() - { - return "ver_" + major + "_" + minor; - } - - public String toString() - { - return major + "-" + minor; - } + public AmqpVersion(int major, int minor) + { + _major = major; + _minor = minor; + } + + public AmqpVersion(AmqpVersion version) + { + _major = version.getMajor(); + _minor = version.getMinor(); + } + + public int getMajor() + { + return _major; + } + + public int getMinor() + { + return _minor; + } + + public int compareTo(AmqpVersion v) + { + if (_major != v.getMajor()) + { + return _major - v.getMajor(); + } + if (_minor != v.getMinor()) + { + return _minor - v.getMinor(); + } + return 0; + } + + public String namespace() + { + return "ver_" + _major + "_" + _minor; + } + + public String toString() + { + return _major + "-" + _minor; + } } diff --git a/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java b/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java index 4406893cbb..6419e23a1e 100644 --- a/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java +++ b/gentools/src/org/apache/qpid/gentools/AmqpVersionSet.java @@ -21,7 +21,6 @@ package org.apache.qpid.gentools; import java.io.PrintStream; -//import java.util.ArrayList; import java.util.Iterator; import java.util.TreeSet; @@ -30,35 +29,39 @@ public class AmqpVersionSet extends TreeSet implements Printable, C { public AmqpVersionSet() { - super(); + super(); } - + public AmqpVersionSet(AmqpVersion version) { - super(); + super(); add(version); } - + public AmqpVersion find(AmqpVersion version) { - for (AmqpVersion v : this) - { - if (v.compareTo(version) == 0) - return v; - } - return null; + for (AmqpVersion v : this) + { + if (v.compareTo(version) == 0) + { + return v; + } + } + return null; + } + + public void print(PrintStream out, int marginSize, int tabSize) + { + out.print(Utils.createSpaces(marginSize) + "Version Set: " + toString() + Utils.LINE_SEPARATOR); } - - public void print(PrintStream out, int marginSize, int tabSize) - { - out.print(Utils.createSpaces(marginSize) + "Version Set: " + toString() + Utils.lineSeparator); - } - + public int compareTo(AmqpVersionSet other) { int res = size() - other.size(); if (res != 0) + { return res; + } Iterator vItr = iterator(); Iterator oItr = other.iterator(); while (vItr.hasNext() && oItr.hasNext()) @@ -67,7 +70,9 @@ public class AmqpVersionSet extends TreeSet implements Printable, C AmqpVersion oVersion = oItr.next(); res = version.compareTo(oVersion); if (res != 0) + { return res; + } } return 0; } diff --git a/gentools/src/org/apache/qpid/gentools/CppGenerator.java b/gentools/src/org/apache/qpid/gentools/CppGenerator.java index 06454ddeb9..4f58cba34e 100644 --- a/gentools/src/org/apache/qpid/gentools/CppGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/CppGenerator.java @@ -21,37 +21,35 @@ package org.apache.qpid.gentools; import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Iterator; import java.util.TreeMap; public class CppGenerator extends Generator { - protected static final String versionNamespaceStartToken = "${version_namespace_start}"; - protected static final String versionNamespaceEndToken = "${version_namespace_end}"; - - // TODO: Move this to parent class - protected static final int FIELD_NAME = 0; - protected static final int FIELD_CODE_TYPE = 1; - + protected static final String versionNamespaceStartToken = "${version_namespace_start}"; + protected static final String versionNamespaceEndToken = "${version_namespace_end}"; + + // TODO: Move this to parent class + protected static final int FIELD_NAME = 0; + protected static final int FIELD_CODE_TYPE = 1; + /** * A complete list of C++ reserved words. The names of varous XML elements within the AMQP * specification file are used for C++ identifier names in the generated code. Each proposed * name is checked against this list and is modified (by adding an '_' to the end of the * name - see function parseForReservedWords()) if found to be present. */ - protected static final String[] cppReservedWords = {"and", "and_eq", "asm", "auto", "bitand", - "bitor", "bool", "break", "case", "catch", "char", "class", "compl", "const", "const_cast", - "continue", "default", "delete", "do", "DomainInfo", "double", "dynamic_cast", "else", - "enum", "explicit", "extern", "false", "float", "for", "friend", "goto", "if", "inline", - "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq", - "private", "protected", "public", "register", "reinterpret_cast", "return", "short", - "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", "this", - "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", - "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"}; - + protected static final String[] cppReservedWords = {"and", "and_eq", "asm", "auto", "bitand", + "bitor", "bool", "break", "case", "catch", "char", "class", "compl", "const", "const_cast", + "continue", "default", "delete", "do", "DomainInfo", "double", "dynamic_cast", "else", + "enum", "explicit", "extern", "false", "float", "for", "friend", "goto", "if", "inline", + "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq", + "private", "protected", "public", "register", "reinterpret_cast", "return", "short", + "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", "this", + "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", + "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq"}; + /** * Although not reserved words, the following list of variable names that may cause compile * problems within a C++ environment because they clash with common #includes. The names of @@ -61,87 +59,89 @@ public class CppGenerator extends Generator * to be present. This list is best added to on an as-needed basis. */ protected static final String[] cppCommonDefines = {"string"}; - + // TODO: Move this to the Generator superclass? protected boolean quietFlag; // Supress warning messages to the console - - private class DomainInfo - { - public String type; - public String size; - public String encodeExpression; - public String decodeExpression; - public DomainInfo(String domain, String size, String encodeExpression, - String decodeExpression) - { - this.type = domain; - this.size = size; - this.encodeExpression = encodeExpression; - this.decodeExpression = decodeExpression; - } - } - - private static TreeMap typeMap = new TreeMap(); - - public CppGenerator(AmqpVersionSet versionList) - { - super(versionList); + + private class DomainInfo + { + public String type; + public String size; + public String encodeExpression; + public String decodeExpression; + + public DomainInfo(String domain, String size, String encodeExpression, + String decodeExpression) + { + this.type = domain; + this.size = size; + this.encodeExpression = encodeExpression; + this.decodeExpression = decodeExpression; + } + } + + private static TreeMap typeMap = new TreeMap(); + + public CppGenerator() + { + super(); quietFlag = true; - // Load C++ type and size maps. - // Adjust or add to these lists as new types are added/defined. - // The char '#' will be replaced by the field variable name (any type). - // The char '~' will be replaced by the compacted bit array size (type bit only). - typeMap.put("bit", new DomainInfo( - "bool", // type - "~", // size - "", // encodeExpression - "")); // decodeExpression - typeMap.put("content", new DomainInfo( - "Content", // type - "#.size()", // size - "buffer.putContent(#)", // encodeExpression - "buffer.getContent(#)")); // decodeExpression - typeMap.put("long", new DomainInfo( - "u_int32_t", // type - "4", // size - "buffer.putLong(#)", // encodeExpression - "# = buffer.getLong()")); // decodeExpression - typeMap.put("longlong", new DomainInfo( - "u_int64_t", // type - "8", // size + // Load C++ type and size maps. + // Adjust or add to these lists as new types are added/defined. + // The char '#' will be replaced by the field variable name (any type). + // The char '~' will be replaced by the compacted bit array size (type bit only). + typeMap.put("bit", new DomainInfo( + "bool", // type + "~", // size + "", // encodeExpression + "")); // decodeExpression + typeMap.put("content", new DomainInfo( + "Content", // type + "#.size()", // size + "buffer.putContent(#)", // encodeExpression + "buffer.getContent(#)")); // decodeExpression + typeMap.put("long", new DomainInfo( + "u_int32_t", // type + "4", // size + "buffer.putLong(#)", // encodeExpression + "# = buffer.getLong()")); // decodeExpression + typeMap.put("longlong", new DomainInfo( + "u_int64_t", // type + "8", // size "buffer.putLongLong(#)", // encodeExpression - "# = buffer.getLongLong()")); // decodeExpression - typeMap.put("longstr", new DomainInfo( - "string", // type - "4 + #.length()", // size + "# = buffer.getLongLong()")); // decodeExpression + typeMap.put("longstr", new DomainInfo( + "string", // type + "4 + #.length()", // size "buffer.putLongString(#)", // encodeExpression - "buffer.getLongString(#)")); // decodeExpression - typeMap.put("octet", new DomainInfo( - "u_int8_t", // type - "1", // size - "buffer.putOctet(#)", // encodeExpression - "# = buffer.getOctet()")); // decodeExpression - typeMap.put("short", new DomainInfo( - "u_int16_t", // type - "2", // size - "buffer.putShort(#)", // encodeExpression - "# = buffer.getShort()")); // decodeExpression - typeMap.put("shortstr", new DomainInfo( - "string", // type - "1 + #.length()", // size + "buffer.getLongString(#)")); // decodeExpression + typeMap.put("octet", new DomainInfo( + "u_int8_t", // type + "1", // size + "buffer.putOctet(#)", // encodeExpression + "# = buffer.getOctet()")); // decodeExpression + typeMap.put("short", new DomainInfo( + "u_int16_t", // type + "2", // size + "buffer.putShort(#)", // encodeExpression + "# = buffer.getShort()")); // decodeExpression + typeMap.put("shortstr", new DomainInfo( + "string", // type + "1 + #.length()", // size "buffer.putShortString(#)", // encodeExpression - "buffer.getShortString(#)")); // decodeExpression - typeMap.put("table", new DomainInfo( - "FieldTable", // type - "#.size()", // size + "buffer.getShortString(#)")); // decodeExpression + typeMap.put("table", new DomainInfo( + "FieldTable", // type + "#.size()", // size "buffer.putFieldTable(#)", // encodeExpression - "buffer.getFieldTable(#)")); // decodeExpression - typeMap.put("timestamp", new DomainInfo( - "u_int64_t", // type - "8", // size + "buffer.getFieldTable(#)")); // decodeExpression + typeMap.put("timestamp", new DomainInfo( + "u_int64_t", // type + "8", // size "buffer.putLongLong(#)", // encodeExpression - "buffer.getLongLong(#)")); // decodeExpression - } + "buffer.getLongLong(#)")); // decodeExpression + } + public boolean isQuietFlag() { @@ -152,40 +152,33 @@ public class CppGenerator extends Generator { this.quietFlag = quietFlag; } - - // === Start of methods for Interface LanguageConverter === - - public String prepareClassName(String className) - { - return camelCaseName(className, true); - } - - public String prepareMethodName(String methodName) - { - return camelCaseName(methodName, false); - } - - public String prepareDomainName(String domainName) - { - return camelCaseName(domainName, false); - } - - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - if (version == null) - version = globalVersionSet.first(); - return globalDomainMap.getDomainType(domainName, version); - } - - public String getGeneratedType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - String domainType = getDomainType(domainName, version); - if (domainType == null) - { - throw new AmqpTypeMappingException("Domain type \"" + domainName + - "\" not found in C++ typemap."); + + // === Start of methods for Interface LanguageConverter === + + public String prepareClassName(String className) + { + return camelCaseName(className, true); + } + + public String prepareMethodName(String methodName) + { + return camelCaseName(methodName, false); + } + + public String prepareDomainName(String domainName) + { + return camelCaseName(domainName, false); + } + + + public String getGeneratedType(String domainName, AmqpVersion version) + throws AmqpTypeMappingException + { + String domainType = getDomainType(domainName, version); + if (domainType == null) + { + throw new AmqpTypeMappingException("Domain type \"" + domainName + + "\" not found in C++ typemap."); } DomainInfo info = typeMap.get(domainType); if (info == null) @@ -193,228 +186,255 @@ public class CppGenerator extends Generator throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); } return info.type; - } - - // === Abstract methods from class Generator - C++-specific implementation === - - @Override - protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, - AmqpField field) - { - StringBuffer sb = new StringBuffer(filenameTemplate); - if (thisClass != null) - replaceToken(sb, "${CLASS}", thisClass.name); - if (method != null) - replaceToken(sb, "${METHOD}", method.name); - if (field != null) - replaceToken(sb, "${FIELD}", field.name); - return sb.toString(); - } - - @Override - protected void processTemplateA(String[] template) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[templateStringIndex]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null); - boolean templateProcessedFlag = false; - - // If method is not version consistent, create a namespace for each version - // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken - // once for each namespace. - if (method != null) - { - if (!method.isVersionConsistent(globalVersionSet)) - { - int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken); - int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) + - versionNamespaceEndToken.length(); - if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 && - namespaceStartIndex <= namespaceEndIndex) - { - String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + cr; - sb.delete(namespaceStartIndex, namespaceEndIndex); - for (AmqpVersion v : method.versionSet) - { - StringBuffer nssb = new StringBuffer(namespaceSpan); - processTemplate(nssb, thisClass, method, null, template[templateFileNameIndex], v); - sb.insert(namespaceStartIndex, nssb); - } + } + + // === Abstract methods from class Generator - C++-specific implementation === + + @Override + protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(filenameTemplate); + if (thisClass != null) + { + replaceToken(sb, "${CLASS}", thisClass.getName()); + } + if (method != null) + { + replaceToken(sb, "${METHOD}", method.getName()); + } + if (field != null) + { + replaceToken(sb, "${FIELD}", field.getName()); + } + return sb.toString(); + } + + @Override + protected void processModelTemplate(NamedTemplate template) + { + processTemplate(template, null, null, null, null); + } + + @Override + protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass) + { + processTemplate(template, thisClass, null, null, null); + } + + @Override + protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method) + { + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, null, null); + boolean templateProcessedFlag = false; + + // If method is not version consistent, create a namespace for each version + // i.e. copy the bit between the versionNamespaceStartToken and versionNamespaceEndToken + // once for each namespace. + if (method != null) + { + if (!method.isVersionConsistent(getVersionSet())) + { + int namespaceStartIndex = sb.indexOf(versionNamespaceStartToken); + int namespaceEndIndex = sb.indexOf(versionNamespaceEndToken) + + versionNamespaceEndToken.length(); + if (namespaceStartIndex >= 0 && namespaceEndIndex >= 0 && + namespaceStartIndex <= namespaceEndIndex) + { + String namespaceSpan = sb.substring(namespaceStartIndex, namespaceEndIndex) + CR; + sb.delete(namespaceStartIndex, namespaceEndIndex); + for (AmqpVersion v : method.getVersionSet()) + { + StringBuffer nssb = new StringBuffer(namespaceSpan); + processTemplate(nssb, thisClass, method, null, template.getName(), v); + sb.insert(namespaceStartIndex, nssb); + } // Process all tokens *not* within the namespace span prior to inserting namespaces - processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); - } - templateProcessedFlag = true; - } - } - // Remove any remaining namespace tags - int nsTokenIndex = sb.indexOf(versionNamespaceStartToken); - while (nsTokenIndex > 0) - { - sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length()); - nsTokenIndex = sb.indexOf(versionNamespaceStartToken); - } - nsTokenIndex = sb.indexOf(versionNamespaceEndToken); - while (nsTokenIndex > 0) - { - sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length()); - nsTokenIndex = sb.indexOf(versionNamespaceEndToken); - } - - if (!templateProcessedFlag) - { - processTemplate(sb, thisClass, method, null, template[templateFileNameIndex], null); - } - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, AmqpMethod method, - AmqpField field) - throws IOException, AmqpTemplateException, AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - StringBuffer sb = new StringBuffer(template[templateStringIndex]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - processTemplate(sb, thisClass, method, field, template[templateFileNameIndex], null); - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, - AmqpField field, String templateFileName, AmqpVersion version) - throws InvocationTargetException, IllegalAccessException, AmqpTypeMappingException - { - try { processAllLists(sb, thisClass, method, version); } - catch (AmqpTemplateException e) - { - System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, version); } - catch (AmqpTemplateException e) - { - System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); - } - } - - @Override - protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, - AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - if (token.compareTo("${GENERATOR}") == 0) - return generatorInfo; - if (token.compareTo("${CLASS}") == 0 && thisClass != null) - return thisClass.name; - if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) - { - if (version == null) - return String.valueOf(thisClass.indexMap.firstKey()); - return getIndex(thisClass.indexMap, version); - } - if (token.compareTo("${METHOD}") == 0 && method != null) - return method.name; - if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) - { - if (version == null) - return String.valueOf(method.indexMap.firstKey()); - return getIndex(method.indexMap, version); - } - if (token.compareTo("${FIELD}") == 0 && field != null) - return field.name; - if (token.compareTo(versionNamespaceStartToken) == 0 && version != null) - return "namespace " + version.namespace() + cr + "{"; - if (token.compareTo(versionNamespaceEndToken) == 0 && version != null) - return "} // namespace " + version.namespace(); + processTemplate(sb, thisClass, method, null, template.getName(), null); + } + templateProcessedFlag = true; + } + } + // Remove any remaining namespace tags + int nsTokenIndex = sb.indexOf(versionNamespaceStartToken); + while (nsTokenIndex > 0) + { + sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceStartToken.length()); + nsTokenIndex = sb.indexOf(versionNamespaceStartToken); + } + nsTokenIndex = sb.indexOf(versionNamespaceEndToken); + while (nsTokenIndex > 0) + { + sb.delete(nsTokenIndex, nsTokenIndex + versionNamespaceEndToken.length()); + nsTokenIndex = sb.indexOf(versionNamespaceEndToken); + } + + if (!templateProcessedFlag) + { + processTemplate(sb, thisClass, method, null, template.getName(), null); + } + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + @Override + protected void processTemplate(NamedTemplate template, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version); + processTemplate(sb, thisClass, method, field, template.getName(), null); + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, + AmqpField field, String templateFileName, AmqpVersion version) + { + try + { + processAllLists(sb, thisClass, method, version); + } + catch (AmqpTemplateException e) + { + System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); + } + try + { + processAllTokens(sb, thisClass, method, field, version); + } + catch (AmqpTemplateException e) + { + System.out.println("ERROR: " + templateFileName + ": " + e.getMessage()); + } + } + + @Override + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) + { + if (token.compareTo("${GENERATOR}") == 0) + { + return GENERATOR_INFO; + } + if (token.compareTo("${CLASS}") == 0 && thisClass != null) + { + return thisClass.getName(); + } + if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) + { + if (version == null) + { + return String.valueOf(thisClass.getIndexMap().firstKey()); + } + return getIndex(thisClass.getIndexMap(), version); + } + if (token.compareTo("${METHOD}") == 0 && method != null) + { + return method.getName(); + } + if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) + { + if (version == null) + { + return String.valueOf(method.getIndexMap().firstKey()); + } + return getIndex(method.getIndexMap(), version); + } + if (token.compareTo("${FIELD}") == 0 && field != null) + { + return field.getName(); + } + if (token.compareTo(versionNamespaceStartToken) == 0 && version != null) + { + return "namespace " + version.namespace() + CR + "{"; + } + if (token.compareTo(versionNamespaceEndToken) == 0 && version != null) + { + return "} // namespace " + version.namespace(); + } if (token.compareTo("${mb_constructor_with_initializers}") == 0) + { return generateConstructor(thisClass, method, version, 4, 4); + } if (token.compareTo("${mb_server_operation_invoke}") == 0) + { return generateServerOperationsInvoke(thisClass, method, version, 4, 4); + } if (token.compareTo("${mb_buffer_param}") == 0) - return method.fieldMap.size() > 0 ? " buffer" : ""; + { + return method.getFieldMap().size() > 0 ? " buffer" : ""; + } if (token.compareTo("${hv_latest_major}") == 0) - return String.valueOf(globalVersionSet.last().getMajor()); + { + return String.valueOf(getVersionSet().last().getMajor()); + } if (token.compareTo("${hv_latest_minor}") == 0) - return String.valueOf(globalVersionSet.last().getMinor()); - - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - - @Override - protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpModel model) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // ClientOperations.h - if (token.compareTo("${coh_method_handler_get_method}") == 0) - { - codeSnippet = generateOpsMethodHandlerGetMethods(model, false, 4); - } - else if (token.compareTo("${coh_inner_class}") == 0) - { - codeSnippet = generateOpsInnerClasses(model, false, 4, 4); - } - - // ServerOperations.h - else if (token.compareTo("${soh_method_handler_get_method}") == 0) - { - codeSnippet = generateOpsMethodHandlerGetMethods(model, true, 4); - } - else if (token.compareTo("${soh_inner_class}") == 0) - { - codeSnippet = generateOpsInnerClasses(model, true, 4, 4); - } - - // ClientProxy.h/cpp - else if (token.compareTo("${cph_inner_class_instance}") == 0) - { - codeSnippet = generateProxyInnerClassInstances(model, false, 4); - } - else if (token.compareTo("${cph_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodDecls(model, false, 4); - } - else if (token.compareTo("${cph_inner_class_defn}") == 0) - { - codeSnippet = generateProxyInnerClassDefinitions(model, false, 4, 4); - } - else if (token.compareTo("${cpc_constructor_initializer}") == 0) - { - codeSnippet = generateProxyConstructorInitializers(model, false, 4); - } - else if (token.compareTo("${cpc_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodImpls(model, false, 0, 4); - } - else if (token.compareTo("${cpc_inner_class_impl}") == 0) - { - codeSnippet = generateProxyInnerClassImpl(model, false, 0, 4); - } + { + return String.valueOf(getVersionSet().last().getMinor()); + } + + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + @Override + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model, AmqpVersion version) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokxStart = tline.indexOf('$'); + String token = tline.substring(tokxStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + // ClientOperations.h + if (token.compareTo("${coh_method_handler_get_method}") == 0) + { + codeSnippet = generateOpsMethodHandlerGetMethods(model, false, 4); + } + else if (token.compareTo("${coh_inner_class}") == 0) + { + codeSnippet = generateOpsInnerClasses(model, false, 4, 4); + } + + // ServerOperations.h + else if (token.compareTo("${soh_method_handler_get_method}") == 0) + { + codeSnippet = generateOpsMethodHandlerGetMethods(model, true, 4); + } + else if (token.compareTo("${soh_inner_class}") == 0) + { + codeSnippet = generateOpsInnerClasses(model, true, 4, 4); + } + + // ClientProxy.h/cpp + else if (token.compareTo("${cph_inner_class_instance}") == 0) + { + codeSnippet = generateProxyInnerClassInstances(model, false, 4); + } + else if (token.compareTo("${cph_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodDecls(model, false, 4); + } + else if (token.compareTo("${cph_inner_class_defn}") == 0) + { + codeSnippet = generateProxyInnerClassDefinitions(model, false, 4, 4); + } + else if (token.compareTo("${cpc_constructor_initializer}") == 0) + { + codeSnippet = generateProxyConstructorInitializers(model, false, 4); + } + else if (token.compareTo("${cpc_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodImpls(model, false, 0, 4); + } + else if (token.compareTo("${cpc_inner_class_impl}") == 0) + { + codeSnippet = generateProxyInnerClassImpl(model, false, 0, 4); + } else if (token.compareTo("${cph_handler_pointer_defn}") == 0) { codeSnippet = generateHandlerPointerDefinitions(model, false, 4); @@ -423,32 +443,32 @@ public class CppGenerator extends Generator { codeSnippet = generateHandlerPointerGetMethods(model, false, 4); } - - // SerrverProxy.h/cpp - else if (token.compareTo("${sph_inner_class_instance}") == 0) - { - codeSnippet = generateProxyInnerClassInstances(model, true, 4); - } - else if (token.compareTo("${sph_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodDecls(model, true, 4); - } - else if (token.compareTo("${sph_inner_class_defn}") == 0) - { - codeSnippet = generateProxyInnerClassDefinitions(model, true, 4, 4); - } - else if (token.compareTo("${spc_constructor_initializer}") == 0) - { - codeSnippet = generateProxyConstructorInitializers(model, true, 4); - } - else if (token.compareTo("${spc_inner_class_get_method}") == 0) - { - codeSnippet = generateProxyInnerClassGetMethodImpls(model, true, 0, 4); - } - else if (token.compareTo("${spc_inner_class_impl}") == 0) - { - codeSnippet = generateProxyInnerClassImpl(model, true, 0, 4); - } + + // SerrverProxy.h/cpp + else if (token.compareTo("${sph_inner_class_instance}") == 0) + { + codeSnippet = generateProxyInnerClassInstances(model, true, 4); + } + else if (token.compareTo("${sph_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodDecls(model, true, 4); + } + else if (token.compareTo("${sph_inner_class_defn}") == 0) + { + codeSnippet = generateProxyInnerClassDefinitions(model, true, 4, 4); + } + else if (token.compareTo("${spc_constructor_initializer}") == 0) + { + codeSnippet = generateProxyConstructorInitializers(model, true, 4); + } + else if (token.compareTo("${spc_inner_class_get_method}") == 0) + { + codeSnippet = generateProxyInnerClassGetMethodImpls(model, true, 0, 4); + } + else if (token.compareTo("${spc_inner_class_impl}") == 0) + { + codeSnippet = generateProxyInnerClassImpl(model, true, 0, 4); + } else if (token.compareTo("${sph_handler_pointer_defn}") == 0) { codeSnippet = generateHandlerPointerDefinitions(model, true, 4); @@ -457,7 +477,7 @@ public class CppGenerator extends Generator { codeSnippet = generateHandlerPointerGetMethods(model, true, 4); } - + // amqp_methods.h/cpp else if (token.compareTo("${mh_method_body_class_indlude}") == 0) { @@ -471,26 +491,25 @@ public class CppGenerator extends Generator { codeSnippet = generateMethodBodyMapEntry(model, 4); } - - else // Oops! - { - throw new AmqpTemplateException("Template token \"" + token + "\" unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpClass thisClass) - throws AmqpTemplateException, AmqpTypeMappingException - { + + else // Oops! + { + throw new AmqpTemplateException("Template token \"" + token + "\" unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpClass thisClass) + { String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr int tokxStart = tline.indexOf('$'); String token = tline.substring(tokxStart).trim(); sb.delete(listMarkerStartIndex, lend); - + if (token.compareTo("${cpc_method_body_include}") == 0) { codeSnippet = generateMethodBodyIncludes(thisClass, 0); @@ -503,71 +522,68 @@ public class CppGenerator extends Generator { codeSnippet = generateMethodBodyIncludes(thisClass, 0); } - + + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpFieldMap fieldMap, AmqpVersion version) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokxStart = tline.indexOf('$'); + String token = tline.substring(tokxStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + if (token.compareTo("${mb_field_declaration}") == 0) + { + codeSnippet = generateFieldDeclarations(fieldMap, version, 4); + } + else if (token.compareTo("${mb_field_get_method}") == 0) + { + codeSnippet = generateFieldGetMethods(fieldMap, version, 4); + } + else if (token.compareTo("${mb_field_print}") == 0) + { + codeSnippet = generatePrintMethodContents(fieldMap, version, 8); + } + else if (token.compareTo("${mb_body_size}") == 0) + { + codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8); + } + else if (token.compareTo("${mb_encode}") == 0) + { + codeSnippet = generateEncodeMethodContents(fieldMap, version, 8); + } + else if (token.compareTo("${mb_decode}") == 0) + { + codeSnippet = generateDecodeMethodContents(fieldMap, version, 8); + } + else // Oops! { throw new AmqpTemplateException("Template token " + token + " unknown."); } sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpFieldMap fieldMap, AmqpVersion version) - throws AmqpTypeMappingException, AmqpTemplateException, IllegalAccessException, - InvocationTargetException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokxStart = tline.indexOf('$'); - String token = tline.substring(tokxStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - if (token.compareTo("${mb_field_declaration}") == 0) - { - codeSnippet = generateFieldDeclarations(fieldMap, version, 4); - } - else if (token.compareTo("${mb_field_get_method}") == 0) - { - codeSnippet = generateFieldGetMethods(fieldMap, version, 4); - } - else if (token.compareTo("${mb_field_print}") == 0) - { - codeSnippet = generatePrintMethodContents(fieldMap, version, 8); - } - else if (token.compareTo("${mb_body_size}") == 0) - { - codeSnippet = generateBodySizeMethodContents(fieldMap, version, 8); - } - else if (token.compareTo("${mb_encode}") == 0) - { - codeSnippet = generateEncodeMethodContents(fieldMap, version, 8); - } - else if (token.compareTo("${mb_decode}") == 0) - { - codeSnippet = generateDecodeMethodContents(fieldMap, version, 8); - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } + } @Override protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) - throws AmqpTemplateException, AmqpTypeMappingException + AmqpConstantSet constantSet) { String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr int tokxStart = tline.indexOf('$'); String token = tline.substring(tokxStart).trim(); sb.delete(listMarkerStartIndex, lend); - + if (token.compareTo("${ch_get_value_method}") == 0) { codeSnippet = generateConstantGetMethods(constantSet, 4, 4); @@ -579,36 +595,35 @@ public class CppGenerator extends Generator } sb.insert(listMarkerStartIndex, codeSnippet); } - - // === Protected and private helper functions unique to C++ implementation === - + + // === Protected and private helper functions unique to C++ implementation === + // Methods for generation of code snippets for AMQP_Constants.h file - + protected String generateConstantGetMethods(AmqpConstantSet constantSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - for (AmqpConstant thisConstant : constantSet) + for (AmqpConstant thisConstant : constantSet.getContstants()) { - if (thisConstant.isVersionConsistent(globalVersionSet)) + if (thisConstant.isVersionConsistent(getVersionSet())) { // return a constant String value = thisConstant.firstKey(); - sb.append(indent + "static const char* " + thisConstant.name + "() { return \"" + - thisConstant.firstKey() + "\"; }" + cr); + sb.append(indent + "static const char* " + thisConstant.getName() + "() { return \"" + + thisConstant.firstKey() + "\"; }" + CR); if (Utils.containsOnlyDigits(value)) { - sb.append(indent + "static int " + thisConstant.name + "AsInt() { return " + - thisConstant.firstKey() + "; }" + cr); + sb.append(indent + "static int " + thisConstant.getName() + "AsInt() { return " + + thisConstant.firstKey() + "; }" + CR); } if (Utils.containsOnlyDigitsAndDecimal(value)) { - sb.append(indent + "static double " + thisConstant.name + "AsDouble() { return (double)" + - thisConstant.firstKey() + "; }" + cr); + sb.append(indent + "static double " + thisConstant.getName() + "AsDouble() { return (double)" + + thisConstant.firstKey() + "; }" + CR); } - sb.append(cr); + sb.append(CR); } else { @@ -616,559 +631,595 @@ public class CppGenerator extends Generator sb.append(generateVersionDependentGet(thisConstant, "const char*", "", "\"", "\"", indentSize, tabSize)); sb.append(generateVersionDependentGet(thisConstant, "int", "AsInt", "", "", indentSize, tabSize)); sb.append(generateVersionDependentGet(thisConstant, "double", "AsDouble", "(double)", "", indentSize, tabSize)); - sb.append(cr); + sb.append(CR); } - } - return sb.toString(); + } + return sb.toString(); } - + protected String generateVersionDependentGet(AmqpConstant constant, String methodReturnType, - String methodNameSuffix, String returnPrefix, String returnPostfix, int indentSize, int tabSize) - throws AmqpTypeMappingException + String methodNameSuffix, String returnPrefix, String returnPostfix, int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - sb.append(indent + methodReturnType + " " + constant.name + methodNameSuffix + - "() const" + cr); - sb.append(indent + "{" + cr); + sb.append(indent + methodReturnType + " " + constant.getName() + methodNameSuffix + + "() const" + CR); + sb.append(indent + "{" + CR); boolean first = true; for (String thisValue : constant.keySet()) { AmqpVersionSet versionSet = constant.get(thisValue); sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) + - ")" + cr); - sb.append(indent + tab + "{" + cr); + ")" + CR); + sb.append(indent + tab + "{" + CR); if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(thisValue)) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); } else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(thisValue)) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); } else { - sb.append(indent + tab + tab + "return " + returnPrefix + thisValue + returnPostfix + ";" + cr); + sb.append(indent + tab + tab + "return " + returnPrefix + thisValue + returnPostfix + ";" + CR); } - sb.append(indent + tab + "}" + cr); + sb.append(indent + tab + "}" + CR); first = false; } - sb.append(indent + tab + "else" + cr); - sb.append(indent + tab + "{" + cr); - sb.append(indent + tab + tab + "std::stringstream ss;" + cr); - sb.append(indent + tab + tab + "ss << \"Constant \\\"" + constant.name + - "\\\" is undefined for AMQP version \" <<" + cr); - sb.append(indent + tab + tab + tab + "version.toString() << \".\";" + cr); - sb.append(indent + tab + tab + "throw ProtocolVersionException(ss.str());" + cr); - sb.append(indent + tab + "}" + cr); - sb.append(indent + "}" + cr); - return sb.toString(); - } - + sb.append(indent + tab + "else" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "std::stringstream ss;" + CR); + sb.append(indent + tab + tab + "ss << \"Constant \\\"" + constant.getName() + + "\\\" is undefined for AMQP version \" <<" + CR); + sb.append(indent + tab + tab + tab + "version.toString() << \".\";" + CR); + sb.append(indent + tab + tab + "throw ProtocolVersionException(ss.str());" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + "}" + CR); + return sb.toString(); + } + protected String generateConstantDeclarationException(String name, String methodReturnType, - int indentSize, int tabSize) + int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - sb.append(indent + "std::stringstream ss;" + cr); + sb.append(indent + "std::stringstream ss;" + CR); sb.append(indent + "ss << \"Constant \\\"" + name + "\\\" cannot be converted to type " + - methodReturnType + " for AMQP version \" <<" + cr); - sb.append(indent + tab + "version.toString() << \".\";" + cr); - sb.append(indent + "throw ProtocolVersionException(ss.str());" + cr); - return sb.toString(); - } - - // Methods used for generation of code snippets for Server/ClientOperations class generation - - protected String generateOpsMethodHandlerGetMethods(AmqpModel model, boolean serverFlag, int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - // Only generate for this class if there is at least one method of the - // required chassis (server/client flag). - boolean chassisFoundFlag = false; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - chassisFoundFlag = true; - } - if (chassisFoundFlag) - { - sb.append(indent + "virtual AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + - thisClass.name + "Handler* get" + thisClass.name + "Handler() = 0;" + cr); - } - } - return sb.toString(); - } - - protected String generateOpsInnerClasses(AmqpModel model, boolean serverFlag, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - - String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String handlerClassName = thisClass.name + "Handler"; - if (!first) - sb.append(cr); - sb.append(indent + "// ==================== class " + handlerClassName + - " ====================" + cr); - sb.append(indent + "class " + handlerClassName); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(indent + "private:" + cr); - sb.append(indent + tab + proxyClassName+ "* parent;" + cr); - sb.append(cr); - sb.append(indent + tab + "// Constructors and destructors" + cr); - sb.append(cr); - sb.append(indent + "protected:" + cr); - sb.append(indent + tab + handlerClassName + "() {}" + cr); - sb.append(indent + "public:" + cr); - sb.append(indent + tab + handlerClassName + - "(" + proxyClassName + "* _parent) {parent = _parent;}" + cr); - sb.append(indent + tab + "virtual ~" + handlerClassName + "() {}" + cr); - sb.append(cr); - sb.append(indent + tab + "// Protocol methods" + cr); - sb.append(cr); - sb.append(generateInnerClassMethods(thisClass, serverFlag, true, indentSize + tabSize, tabSize)); - sb.append(indent + "}; // class " + handlerClassName + cr); - first = false; - } - return sb.toString(); - } - - protected String generateInnerClassMethods(AmqpClass thisClass, boolean serverFlag, - boolean abstractMethodFlag, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + (abstractMethodFlag ? "Operations" : "Proxy"); - boolean first = true; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - { - String methodName = parseForReservedWords(method.name, outerClassName + "." + thisClass.name); - AmqpOverloadedParameterMap overloadededParameterMap = - method.getOverloadedParameterLists(thisClass.versionSet, this); - for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) - { - AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); - if (!first) - sb.append(cr); - sb.append(indent + "virtual void " + methodName + "( u_int16_t channel"); - sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5*tabSize), true, true, true)); - sb.append(" )"); - if (abstractMethodFlag) - sb.append(" = 0"); - sb.append(";"); - if (versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + versionSet); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - // Methods used for generation of code snippets for Server/ClientProxy class generation + methodReturnType + " for AMQP version \" <<" + CR); + sb.append(indent + tab + "version.toString() << \".\";" + CR); + sb.append(indent + "throw ProtocolVersionException(ss.str());" + CR); + return sb.toString(); + } - protected String generateHandlerPointerDefinitions(AmqpModel model, boolean serverFlag, - int indentSize) + // 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(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; - for (String thisClassName : model.classMap.keySet()) + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - sb.append(indent + outerClassName + "::" + thisClass.name + "Handler* " + - thisClass.name + "HandlerPtr;" + cr); + AmqpClass thisClass = model.getClassMap().get(thisClassName); + // Only generate for this class if there is at least one method of the + // required chassis (server/client flag). + boolean chassisFoundFlag = false; + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + boolean clientChassisFlag = method.getClientMethodFlagMap().isSet(); + boolean serverChassisFlag = method.getServerMethodFlagMap().isSet(); + if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) + { + chassisFoundFlag = true; + } + } + if (chassisFoundFlag) + { + sb.append(indent + "virtual AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + + thisClass.getName() + "Handler* get" + thisClass.getName() + "Handler() = 0;" + CR); + } } return sb.toString(); } - - protected String generateHandlerPointerGetMethods(AmqpModel model, boolean serverFlag, - int indentSize) + + protected String generateOpsInnerClasses(AmqpModel model, boolean serverFlag, int indentSize, int tabSize) { + + String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; - for (String thisClassName : model.classMap.keySet()) + boolean first = true; + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - sb.append(indent + "virtual inline " + outerClassName + "::" + thisClass.name + "Handler* get" + - thisClass.name + "Handler() { return &" + Utils.firstLower(thisClass.name) + ";}" + cr); + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String handlerClassName = thisClass.getName() + "Handler"; + if (!first) + { + sb.append(CR); + } + sb.append(indent + "// ==================== class " + handlerClassName + + " ====================" + CR); + sb.append(indent + "class " + handlerClassName); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + sb.append(indent + "{" + CR); + sb.append(indent + "private:" + CR); + sb.append(indent + tab + proxyClassName + "* parent;" + CR); + sb.append(CR); + sb.append(indent + tab + "// Constructors and destructors" + CR); + sb.append(CR); + sb.append(indent + "protected:" + CR); + sb.append(indent + tab + handlerClassName + "() {}" + CR); + sb.append(indent + "public:" + CR); + sb.append(indent + tab + handlerClassName + + "(" + proxyClassName + "* _parent) {parent = _parent;}" + CR); + sb.append(indent + tab + "virtual ~" + handlerClassName + "() {}" + CR); + sb.append(CR); + sb.append(indent + tab + "// Protocol methods" + CR); + sb.append(CR); + sb.append(generateInnerClassMethods(thisClass, serverFlag, true, indentSize + tabSize, tabSize)); + sb.append(indent + "}; // class " + handlerClassName + CR); + first = false; } return sb.toString(); - } - - protected String generateProxyInnerClassInstances(AmqpModel model, boolean serverFlag, - int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String instanceName = parseForReservedWords(Utils.firstLower(thisClass.name), outerClassName); - String className = parseForReservedWords(thisClass.name, null); - sb.append(indent + className + " " + instanceName + ";"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassGetMethodDecls(AmqpModel model, boolean serverFlag, - int indentSize) - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = parseForReservedWords(thisClass.name, outerClassName); - sb.append(indent + className + "& get" + className + "();"); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassDefinitions(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - boolean first = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = thisClass.name; - String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + - thisClass.name + "Handler"; - if (!first) - sb.append(cr); - sb.append(indent + "// ==================== class " + className + - " ====================" + cr); - sb.append(indent + "class " + className + " : virtual public " + superclassName); - if (thisClass.versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + thisClass.versionSet + cr); - else - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(indent + "private:" + cr); - sb.append(indent + tab + "OutputHandler* out;" + cr); - sb.append(indent + tab + proxyClassName + "* parent;" + cr); - sb.append(cr); - sb.append(indent + "public:" + cr); - sb.append(indent + tab + "// Constructors and destructors" + cr); - sb.append(cr); - sb.append(indent + tab + className + "(OutputHandler* out, " + proxyClassName + "* _parent) : " + cr); - sb.append(indent + tab + tab + "out(out) {parent = _parent;}" + cr); - sb.append(indent + tab + "virtual ~" + className + "() {}" + cr); - sb.append(cr); - sb.append(indent + tab + "// Protocol methods" + cr); - sb.append(cr); - sb.append(generateInnerClassMethods(thisClass, serverFlag, false, indentSize + tabSize, tabSize)); - sb.append(indent + "}; // class " + className + cr); - first = false; - } - return sb.toString(); - } - - protected String generateProxyConstructorInitializers(AmqpModel model, boolean serverFlag, - int indentSize) - { - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(indent + superclassName + "(major, minor)," + cr); - sb.append(indent + "version(major, minor)," + cr); - sb.append(indent + "out(out)"); - Iterator cItr = model.classMap.keySet().iterator(); - while (cItr.hasNext()) - { - AmqpClass thisClass = model.classMap.get(cItr.next()); - String instanceName = parseForReservedWords(Utils.firstLower(thisClass.name), outerClassName); - sb.append("," + cr); - sb.append(indent + instanceName + "(out, this)"); - if (!cItr.hasNext()) - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassGetMethodImpls(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - Iterator cItr = model.classMap.keySet().iterator(); - while (cItr.hasNext()) - { - AmqpClass thisClass = model.classMap.get(cItr.next()); - String className = thisClass.name; - String instanceName = parseForReservedWords(Utils.firstLower(thisClass.name), outerClassName); - sb.append(indent + outerClassName + "::" + className + "& " + - outerClassName + "::get" + className + "()" + cr); - sb.append(indent + "{" + cr); - if (thisClass.versionSet.size() != globalVersionSet.size()) - { - sb.append(indent + tab + "if (!" + generateVersionCheck(thisClass.versionSet) + ")" + cr); - sb.append(indent + tab + tab + "throw new ProtocolVersionException();" + cr); - } - sb.append(indent + tab + "return " + instanceName + ";" + cr); - sb.append(indent + "}" + cr); - if (cItr.hasNext()) - sb.append(cr); - } - return sb.toString(); - } - - protected String generateProxyInnerClassImpl(AmqpModel model, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - boolean firstClassFlag = true; - for (String thisClassName : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(thisClassName); - String className = thisClass.name; - if (!firstClassFlag) - sb.append(cr); - sb.append(indent + "// ==================== class " + className + - " ====================" + cr); - sb.append(generateInnerClassMethodImpls(thisClass, serverFlag, indentSize, tabSize)); - firstClassFlag = false; - } - return sb.toString(); - } - - protected String generateInnerClassMethodImpls(AmqpClass thisClass, boolean serverFlag, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String outerclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; - boolean first = true; - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String methodBodyClassName = thisClass.name + Utils.firstUpper(method.name) + "Body"; - boolean clientChassisFlag = method.clientMethodFlagMap.isSet(); - boolean serverChassisFlag = method.serverMethodFlagMap.isSet(); - boolean versionConsistentFlag = method.isVersionConsistent(globalVersionSet); - if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) - { - String methodName = parseForReservedWords(method.name, outerclassName + "." + thisClass.name); - AmqpOverloadedParameterMap overloadededParameterMap = - method.getOverloadedParameterLists(thisClass.versionSet, this); - for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) - { - AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); - if (!first) - sb.append(cr); - sb.append(indent + "void " + outerclassName + "::" + thisClass.name + "::" + - methodName + "( u_int16_t channel"); - sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5*tabSize), true, true, true)); - sb.append(" )"); - if (versionSet.size() != globalVersionSet.size()) - sb.append(" // AMQP Version(s) " + versionSet); - sb.append(cr); - sb.append(indent + "{" + cr); - sb.append(generateMethodBodyCallContext(thisFieldMap, outerclassName, methodBodyClassName, - versionConsistentFlag, versionSet, indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - sb.append(cr); - first = false; - } - } - } - return sb.toString(); - } - - protected String generateMethodBodyCallContext(AmqpOrdinalFieldMap fieldMap, String outerclassName, - String methodBodyClassName, boolean versionConsistentFlag, AmqpVersionSet versionSet, - int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - if (versionConsistentFlag) - { - sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, null, indentSize, tabSize)); - } - else - { - boolean firstOverloadedMethodFlag = true; - for (AmqpVersion thisVersion : versionSet) - { - sb.append(indent); - if (!firstOverloadedMethodFlag) - sb.append("else "); - sb.append("if (" + generateVersionCheck(thisVersion) + ")" + cr); - sb.append(indent + "{" + cr); - sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, thisVersion, - indentSize + tabSize, tabSize)); - sb.append(indent + "}" + cr); - firstOverloadedMethodFlag = false; - } - sb.append(indent + "else" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "std::stringstream ss;" + cr); - sb.append(indent + tab + "ss << \"Call to " + outerclassName + "::" + methodBodyClassName + - "(u_int16_t" + generateMethodParameterList(fieldMap, 0, true, true, false) + ")\"" + cr); - sb.append(indent + tab + tab + "<< \" is invalid for AMQP version \" << version.toString() << \".\";" + cr); - sb.append(indent + tab + "throw new ProtocolVersionException(ss.str());" + cr); - sb.append(indent + "}" + cr); - } - return sb.toString(); - } - - protected String generateMethodBodyCall(AmqpOrdinalFieldMap fieldMap, String methodBodyClassName, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - String namespace = version != null ? version.namespace() + "::" : ""; - StringBuffer sb = new StringBuffer(indent + "out->send( new AMQFrame(parent->getProtocolVersion(), channel," + cr); - sb.append(indent + tab + "new " + namespace + methodBodyClassName + "( parent->getProtocolVersion()"); - sb.append(generateMethodParameterList(fieldMap, indentSize + (5*tabSize), true, false, true)); - sb.append(" )));" + cr); - return sb.toString(); - } - - protected String generateMethodBodyIncludes(AmqpClass thisClass, int indentSize) + } + + protected String generateInnerClassMethods(AmqpClass thisClass, boolean serverFlag, + boolean abstractMethodFlag, int indentSize, int tabSize) { + String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - if (thisClass != null) + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + (abstractMethodFlag ? "Operations" + : "Proxy"); + boolean first = true; + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - sb.append(generateClassMethodBodyInclude(thisClass, indentSize)); - } - else + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + boolean clientChassisFlag = method.getClientMethodFlagMap().isSet(); + boolean serverChassisFlag = method.getServerMethodFlagMap().isSet(); + if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) + { + String methodName = parseForReservedWords(method.getName(), outerClassName + "." + thisClass.getName()); + AmqpOverloadedParameterMap overloadededParameterMap = + method.getOverloadedParameterLists(thisClass.getVersionSet(), this); + for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) + { + AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); + if (!first) + { + sb.append(CR); + } + sb.append(indent + "virtual void " + methodName + "( u_int16_t channel"); + sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5 * tabSize), true, true, true)); + sb.append(" )"); + if (abstractMethodFlag) + { + sb.append(" = 0"); + } + sb.append(";"); + if (versionSet.size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + versionSet); + } + sb.append(CR); + first = false; + } + } + } + return sb.toString(); + } + + // Methods used for generation of code snippets for Server/ClientProxy class generation + + protected String generateHandlerPointerDefinitions(AmqpModel model, boolean serverFlag, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + sb.append(indent + outerClassName + "::" + thisClass.getName() + "Handler* " + + thisClass.getName() + "HandlerPtr;" + CR); + } + return sb.toString(); + } + + protected String generateHandlerPointerGetMethods(AmqpModel model, boolean serverFlag, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; + for (String thisClassName : model.getClassMap().keySet()) { - for (String thisClassName : model.classMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + sb.append(indent + "virtual inline " + outerClassName + "::" + thisClass.getName() + "Handler* get" + + thisClass.getName() + "Handler() { return &" + Utils.firstLower(thisClass.getName()) + ";}" + CR); + } + return sb.toString(); + } + + protected String generateProxyInnerClassInstances(AmqpModel model, boolean serverFlag, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName); + String className = parseForReservedWords(thisClass.getName(), null); + sb.append(indent + className + " " + instanceName + ";"); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else { - thisClass = model.classMap.get(thisClassName); + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassGetMethodDecls(AmqpModel model, boolean serverFlag, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String className = parseForReservedWords(thisClass.getName(), outerClassName); + sb.append(indent + className + "& get" + className + "();"); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassDefinitions(AmqpModel model, boolean serverFlag, + int indentSize, int tabSize) + { + String proxyClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String className = thisClass.getName(); + String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations::" + + thisClass.getName() + "Handler"; + if (!first) + { + sb.append(CR); + } + sb.append(indent + "// ==================== class " + className + + " ====================" + CR); + sb.append(indent + "class " + className + " : virtual public " + superclassName); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + thisClass.getVersionSet() + CR); + } + else + { + sb.append(CR); + } + sb.append(indent + "{" + CR); + sb.append(indent + "private:" + CR); + sb.append(indent + tab + "OutputHandler* out;" + CR); + sb.append(indent + tab + proxyClassName + "* parent;" + CR); + sb.append(CR); + sb.append(indent + "public:" + CR); + sb.append(indent + tab + "// Constructors and destructors" + CR); + sb.append(CR); + sb.append(indent + tab + className + "(OutputHandler* out, " + proxyClassName + "* _parent) : " + CR); + sb.append(indent + tab + tab + "out(out) {parent = _parent;}" + CR); + sb.append(indent + tab + "virtual ~" + className + "() {}" + CR); + sb.append(CR); + sb.append(indent + tab + "// Protocol methods" + CR); + sb.append(CR); + sb.append(generateInnerClassMethods(thisClass, serverFlag, false, indentSize + tabSize, tabSize)); + sb.append(indent + "}; // class " + className + CR); + first = false; + } + return sb.toString(); + } + + protected String generateProxyConstructorInitializers(AmqpModel model, boolean serverFlag, + int indentSize) + { + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + String superclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Operations"; + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(indent + superclassName + "(major, minor)," + CR); + sb.append(indent + "version(major, minor)," + CR); + sb.append(indent + "out(out)"); + Iterator cItr = model.getClassMap().keySet().iterator(); + while (cItr.hasNext()) + { + AmqpClass thisClass = model.getClassMap().get(cItr.next()); + String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName); + sb.append("," + CR); + sb.append(indent + instanceName + "(out, this)"); + if (!cItr.hasNext()) + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassGetMethodImpls(AmqpModel model, boolean serverFlag, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + String outerClassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + Iterator cItr = model.getClassMap().keySet().iterator(); + while (cItr.hasNext()) + { + AmqpClass thisClass = model.getClassMap().get(cItr.next()); + String className = thisClass.getName(); + String instanceName = parseForReservedWords(Utils.firstLower(thisClass.getName()), outerClassName); + sb.append(indent + outerClassName + "::" + className + "& " + + outerClassName + "::get" + className + "()" + CR); + sb.append(indent + "{" + CR); + if (thisClass.getVersionSet().size() != getVersionSet().size()) + { + sb.append(indent + tab + "if (!" + generateVersionCheck(thisClass.getVersionSet()) + ")" + CR); + sb.append(indent + tab + tab + "throw new ProtocolVersionException();" + CR); + } + sb.append(indent + tab + "return " + instanceName + ";" + CR); + sb.append(indent + "}" + CR); + if (cItr.hasNext()) + { + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateProxyInnerClassImpl(AmqpModel model, boolean serverFlag, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + boolean firstClassFlag = true; + for (String thisClassName : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(thisClassName); + String className = thisClass.getName(); + if (!firstClassFlag) + { + sb.append(CR); + } + sb.append(indent + "// ==================== class " + className + + " ====================" + CR); + sb.append(generateInnerClassMethodImpls(thisClass, serverFlag, indentSize, tabSize)); + firstClassFlag = false; + } + return sb.toString(); + } + + protected String generateInnerClassMethodImpls(AmqpClass thisClass, boolean serverFlag, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String outerclassName = "AMQP_" + (serverFlag ? "Server" : "Client") + "Proxy"; + boolean first = true; + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + String methodBodyClassName = thisClass.getName() + Utils.firstUpper(method.getName()) + "Body"; + boolean clientChassisFlag = method.getClientMethodFlagMap().isSet(); + boolean serverChassisFlag = method.getServerMethodFlagMap().isSet(); + boolean versionConsistentFlag = method.isVersionConsistent(getVersionSet()); + if ((serverFlag && serverChassisFlag) || (!serverFlag && clientChassisFlag)) + { + String methodName = parseForReservedWords(method.getName(), outerclassName + "." + thisClass.getName()); + AmqpOverloadedParameterMap overloadededParameterMap = + method.getOverloadedParameterLists(thisClass.getVersionSet(), this); + for (AmqpOrdinalFieldMap thisFieldMap : overloadededParameterMap.keySet()) + { + AmqpVersionSet versionSet = overloadededParameterMap.get(thisFieldMap); + if (!first) + { + sb.append(CR); + } + sb.append(indent + "void " + outerclassName + "::" + thisClass.getName() + "::" + + methodName + "( u_int16_t channel"); + sb.append(generateMethodParameterList(thisFieldMap, indentSize + (5 * tabSize), true, true, true)); + sb.append(" )"); + if (versionSet.size() != getVersionSet().size()) + { + sb.append(" // AMQP Version(s) " + versionSet); + } + sb.append(CR); + sb.append(indent + "{" + CR); + sb.append(generateMethodBodyCallContext(thisFieldMap, outerclassName, methodBodyClassName, + versionConsistentFlag, versionSet, indentSize + tabSize, tabSize)); + sb.append(indent + "}" + CR); + sb.append(CR); + first = false; + } + } + } + return sb.toString(); + } + + protected String generateMethodBodyCallContext(AmqpOrdinalFieldMap fieldMap, String outerclassName, + String methodBodyClassName, boolean versionConsistentFlag, AmqpVersionSet versionSet, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + if (versionConsistentFlag) + { + sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, null, indentSize, tabSize)); + } + else + { + boolean firstOverloadedMethodFlag = true; + for (AmqpVersion thisVersion : versionSet) + { + sb.append(indent); + if (!firstOverloadedMethodFlag) + { + sb.append("else "); + } + sb.append("if (" + generateVersionCheck(thisVersion) + ")" + CR); + sb.append(indent + "{" + CR); + sb.append(generateMethodBodyCall(fieldMap, methodBodyClassName, thisVersion, + indentSize + tabSize, tabSize)); + sb.append(indent + "}" + CR); + firstOverloadedMethodFlag = false; + } + sb.append(indent + "else" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "std::stringstream ss;" + CR); + sb.append(indent + tab + "ss << \"Call to " + outerclassName + "::" + methodBodyClassName + + "(u_int16_t" + generateMethodParameterList(fieldMap, 0, true, true, false) + ")\"" + CR); + sb.append(indent + tab + tab + "<< \" is invalid for AMQP version \" << version.toString() << \".\";" + CR); + sb.append(indent + tab + "throw new ProtocolVersionException(ss.str());" + CR); + sb.append(indent + "}" + CR); + } + return sb.toString(); + } + + protected String generateMethodBodyCall(AmqpOrdinalFieldMap fieldMap, String methodBodyClassName, + AmqpVersion version, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String namespace = version != null ? version.namespace() + "::" : ""; + StringBuffer sb = new StringBuffer(indent + "out->send( new AMQFrame(parent->getProtocolVersion(), channel," + CR); + sb.append(indent + tab + "new " + namespace + methodBodyClassName + "( parent->getProtocolVersion()"); + sb.append(generateMethodParameterList(fieldMap, indentSize + (5 * tabSize), true, false, true)); + sb.append(" )));" + CR); + return sb.toString(); + } + + protected String generateMethodBodyIncludes(AmqpClass thisClass, int indentSize) + { + StringBuffer sb = new StringBuffer(); + if (thisClass != null) + { + sb.append(generateClassMethodBodyInclude(thisClass, indentSize)); + } + else + { + for (String thisClassName : getModel().getClassMap().keySet()) + { + thisClass = getModel().getClassMap().get(thisClassName); sb.append(generateClassMethodBodyInclude(thisClass, indentSize)); - } + } } - return sb.toString(); + return sb.toString(); } - + protected String generateClassMethodBodyInclude(AmqpClass thisClass, int indentSize) { StringBuffer sb = new StringBuffer(); String indent = Utils.createSpaces(indentSize); - for (String thisMethodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "#include <" + thisClass.name + - Utils.firstUpper(method.name) + "Body.h>" + cr); - } - return sb.toString(); - } - - // Methods used for generation of code snippets for MethodBody class generation - - protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) - throws AmqpTemplateException - { - for (Integer thisIndex : indexMap.keySet()) - { - AmqpVersionSet versionSet = indexMap.get(thisIndex); - if (versionSet.contains(version)) - return String.valueOf(thisIndex); - } - throw new AmqpTemplateException("Unable to find index for version " + version); - } - - protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - + for (String thisMethodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + sb.append(indent + "#include <" + thisClass.getName() + + Utils.firstUpper(method.getName()) + "Body.h>" + CR); + } + return sb.toString(); + } + + // Methods used for generation of code snippets for MethodBody class generation + + protected String getIndex(AmqpOrdinalVersionMap indexMap, AmqpVersion version) + { + for (Integer thisIndex : indexMap.keySet()) + { + AmqpVersionSet versionSet = indexMap.get(thisIndex); + if (versionSet.contains(version)) + { + return String.valueOf(thisIndex); + } + } + throw new AmqpTemplateException("Unable to find index for version " + version); + } + + protected String generateFieldDeclarations(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + if (version == null) - version = globalVersionSet.first(); + { + version = getVersionSet().first(); + } AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); for (Integer thisOrdinal : ordinalFieldMap.keySet()) { String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal); - sb.append(indent + fieldDomainPair[FIELD_CODE_TYPE] + " " + fieldDomainPair[FIELD_NAME] + ";" + cr); - } - return sb.toString(); - } - - protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - + sb.append(indent + fieldDomainPair[FIELD_CODE_TYPE] + " " + fieldDomainPair[FIELD_NAME] + ";" + CR); + } + return sb.toString(); + } + + protected String generateFieldGetMethods(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + if (version == null) - version = globalVersionSet.first(); + { + version = getVersionSet().first(); + } AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); for (Integer thisOrdinal : ordinalFieldMap.keySet()) { String[] fieldDomainPair = ordinalFieldMap.get(thisOrdinal); - sb.append(indent + "inline " + setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " get" + - Utils.firstUpper(fieldDomainPair[FIELD_NAME]) + "() { return " + - fieldDomainPair[FIELD_NAME] + "; }" + cr); - } - return sb.toString(); - } - - protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - + sb.append(indent + "inline " + setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " get" + + Utils.firstUpper(fieldDomainPair[FIELD_NAME]) + "() { return " + + fieldDomainPair[FIELD_NAME] + "; }" + CR); + } + return sb.toString(); + } + + protected String generatePrintMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + if (version == null) - version = globalVersionSet.first(); + { + version = getVersionSet().first(); + } AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); boolean firstFlag = true; for (Integer thisOrdinal : ordinalFieldMap.keySet()) @@ -1177,452 +1228,489 @@ public class CppGenerator extends Generator String cast = fieldDomainPair[FIELD_CODE_TYPE].compareTo("u_int8_t") == 0 ? "(int)" : ""; sb.append(indent + "out << \""); if (!firstFlag) + { sb.append("; "); - sb.append(fieldDomainPair[FIELD_NAME] + "=\" << " + cast + fieldDomainPair[FIELD_NAME] + ";" + cr); + } + sb.append(fieldDomainPair[FIELD_NAME] + "=\" << " + cast + fieldDomainPair[FIELD_NAME] + ";" + CR); firstFlag = false; } - return sb.toString(); - } - - protected String generateBodySizeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, - int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList 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 + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldDomainPair[FIELD_NAME]) + - "; /* " + fieldDomainPair[FIELD_NAME] + ": " + - domainType + " */" + cr); - } - } - if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types - { - sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); - } - return sb.toString(); - } - - protected String generateBitArrayBodySizeMethodContents(ArrayList bitFieldList, - int ordinal, int indentSize) - { - int numBytes = ((bitFieldList.size() - 1) / 8) + 1; - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - String comment = bitFieldList.size() == 1 ? - bitFieldList.get(0) + ": bit" : - "Combinded bits: " + bitFieldList; - sb.append(indent + "size += " + - typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + - "; /* " + comment + " */" + cr); - bitFieldList.clear(); - return sb.toString(); - } - - protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, - int indentSize) - throws AmqpTypeMappingException - { - String indent = Utils.createSpaces(indentSize); - StringBuffer sb = new StringBuffer(); - ArrayList 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(); - } - + return sb.toString(); + } + + protected String generateBodySizeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + { + 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 ? getVersionSet().first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); + + // Defer bit types by adding them to an array. When the first subsequent non-bit + // type is encountered, then handle the bits. This allows consecutive bits to be + // placed into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + + domainType + " */" + CR); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitArrayBodySizeMethodContents(bitFieldList, ordinal, indentSize)); + } + return sb.toString(); + } + + protected String generateBitArrayBodySizeMethodContents(ArrayList bitFieldList, + int ordinal, int indentSize) + { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + sb.append(indent + "size += " + + typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + + "; /* " + comment + " */" + CR); + bitFieldList.clear(); + return sb.toString(); + } + + protected String generateEncodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + ArrayList 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 ? getVersionSet().first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); + + // Defer bit types by adding them to an array. When the first subsequent non-bit + // type is encountered, then handle the bits. This allows consecutive bits to be + // placed into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + + typeMap.get(domainType).encodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + CR); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitEncodeMethodContents(bitFieldList, ordinal, indentSize)); + } + + return sb.toString(); + } + + protected String generateBitEncodeMethodContents(ArrayList bitFieldList, int ordinal, + int indentSize) + { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + String bitArrayName = "flags_" + ordinal; + StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName + + "[" + numBytes + "] = {0};" + + (numBytes != 1 ? " /* All array elements will be initialized to 0 */" : "") + + CR); + for (int i = 0; i < bitFieldList.size(); i++) + { + int bitIndex = i % 8; + int byteIndex = i / 8; + sb.append(indent + bitArrayName + "[" + byteIndex + "] |= " + bitFieldList.get(i) + + " << " + bitIndex + "; /* " + bitFieldList.get(i) + ": bit */" + CR); + } + for (int i = 0; i < numBytes; i++) + { + sb.append(indent + "buffer.putOctet(" + bitArrayName + "[" + i + "]);" + CR); + } + bitFieldList.clear(); + return sb.toString(); + } + + protected String generateDecodeMethodContents(AmqpFieldMap fieldMap, AmqpVersion version, + int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + ArrayList 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 ? getVersionSet().first() : version; + String domainType = getDomainType(fieldDomainPair[FIELD_CODE_TYPE], thisVersion); + + // Defer bit types by adding them to an array. When the first subsequent non-bit + // type is encountered, then handle the bits. This allows consecutive bits to be + // placed into the same byte(s) - 8 bits to the byte. + if (domainType.compareTo("bit") == 0) + { + bitFieldList.add(fieldDomainPair[FIELD_NAME]); + } + else + { + if (bitFieldList.size() > 0) // Handle accumulated bit types (if any) + { + sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); + } + sb.append(indent + + typeMap.get(domainType).decodeExpression.replaceAll("#", fieldDomainPair[FIELD_NAME]) + + "; /* " + fieldDomainPair[FIELD_NAME] + ": " + domainType + " */" + CR); + } + } + if (bitFieldList.size() > 0) // Handle any remaining accumulated bit types + { + sb.append(generateBitDecodeMethodContents(bitFieldList, ordinal, indentSize)); + } + + return sb.toString(); + } + + protected String generateBitDecodeMethodContents(ArrayList bitFieldList, int ordinal, + int indentSize) + { + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String indent = Utils.createSpaces(indentSize); + String bitArrayName = "flags_" + ordinal; + StringBuffer sb = new StringBuffer(indent + "u_int8_t " + bitArrayName + + "[" + numBytes + "];" + CR); + for (int i = 0; i < numBytes; i++) + { + sb.append(indent + bitArrayName + "[" + i + "] = buffer.getOctet();" + CR); + } + for (int i = 0; i < bitFieldList.size(); i++) + { + int bitIndex = i % 8; + int byteIndex = i / 8; + sb.append(indent + bitFieldList.get(i) + " = (1 << " + bitIndex + ") & " + + bitArrayName + "[" + byteIndex + "]; /* " + bitFieldList.get(i) + + ": bit */" + CR); + } + bitFieldList.clear(); + return sb.toString(); + } + + protected String generateFieldList(AmqpFieldMap fieldMap, AmqpVersion version, boolean defineFlag, + boolean initializerFlag, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + AmqpOrdinalFieldMap ordinalFieldMap = fieldMap.getMapForVersion(version, true, this); + Iterator oItr = ordinalFieldMap.keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + String[] fieldDomainPair = ordinalFieldMap.get(ordinal); + sb.append(indent + (defineFlag ? setRef(fieldDomainPair[FIELD_CODE_TYPE]) + " " : "") + + fieldDomainPair[FIELD_NAME] + (initializerFlag ? "(" + fieldDomainPair[FIELD_NAME] + ")" : "") + + (oItr.hasNext() ? "," : "") + CR); + } + return sb.toString(); + } + + protected String generateMethodParameterList(AmqpOrdinalFieldMap fieldMap, int indentSize, + boolean leadingCommaFlag, boolean fieldTypeFlag, boolean fieldNameFlag) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + boolean first = true; + Iterator pItr = fieldMap.keySet().iterator(); + while (pItr.hasNext()) + { + String[] field = fieldMap.get(pItr.next()); + if (first && leadingCommaFlag) + { + sb.append("," + (fieldNameFlag ? CR : " ")); + } + if (!first || leadingCommaFlag) + { + sb.append(indent); + } + sb.append( + (fieldTypeFlag ? setRef(field[FIELD_CODE_TYPE]) : "") + + (fieldNameFlag ? " " + field[FIELD_NAME] : "") + + (pItr.hasNext() ? "," + (fieldNameFlag ? CR : " ") : "")); + first = false; + } + return sb.toString(); + } + protected String generateConstructor(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException + AmqpVersion version, int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - if (method.fieldMap.size() > 0) - { - sb.append(indent + thisClass.name + Utils.firstUpper(method.name) + "Body(ProtocolVersion& version," + cr); - sb.append(generateFieldList(method.fieldMap, version, true, false, 8)); - sb.append(indent + tab + ") :" + cr); - sb.append(indent + tab + "AMQMethodBody(version)," + cr); - sb.append(generateFieldList(method.fieldMap, version, false, true, 8)); - sb.append(indent + "{ }" + cr); - } - return sb.toString(); - } - + if (method.getFieldMap().size() > 0) + { + sb.append(indent + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body(ProtocolVersion& version," + CR); + sb.append(generateFieldList(method.getFieldMap(), version, true, false, 8)); + sb.append(indent + tab + ") :" + CR); + sb.append(indent + tab + "AMQMethodBody(version)," + CR); + sb.append(generateFieldList(method.getFieldMap(), version, false, true, 8)); + sb.append(indent + "{ }" + CR); + } + return sb.toString(); + } + protected String generateServerOperationsInvoke(AmqpClass thisClass, AmqpMethod method, - AmqpVersion version, int indentSize, int tabSize) - throws AmqpTypeMappingException + AmqpVersion version, int indentSize, int tabSize) { String indent = Utils.createSpaces(indentSize); String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - - if (method.serverMethodFlagMap.size() > 0) // At least one AMQP version defines this method as a server method + + if (method.getServerMethodFlagMap().size() > 0) // At least one AMQP version defines this method as a server method { - Iterator bItr = method.serverMethodFlagMap.keySet().iterator(); + Iterator bItr = method.getServerMethodFlagMap().keySet().iterator(); while (bItr.hasNext()) { if (bItr.next()) // This is a server operation { - boolean fieldMapNotEmptyFlag = method.fieldMap.size() > 0; - sb.append(indent + "inline void invoke(AMQP_ServerOperations& target, u_int16_t channel)" + cr); - sb.append(indent + "{" + cr); - sb.append(indent + tab + "target.get" + thisClass.name + "Handler()->" + - parseForReservedWords(Utils.firstLower(method.name), - thisClass.name + Utils.firstUpper(method.name) + "Body.invoke()") + "(channel"); + boolean fieldMapNotEmptyFlag = method.getFieldMap().size() > 0; + sb.append(indent + "inline void invoke(AMQP_ServerOperations& target, u_int16_t channel)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "target.get" + thisClass.getName() + "Handler()->" + + parseForReservedWords(Utils.firstLower(method.getName()), + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body.invoke()") + "(channel"); if (fieldMapNotEmptyFlag) { - sb.append("," + cr); - sb.append(generateFieldList(method.fieldMap, version, false, false, indentSize + 4*tabSize)); - sb.append(indent + tab + tab + tab + tab); + sb.append("," + CR); + sb.append(generateFieldList(method.getFieldMap(), version, false, false, indentSize + 4 * tabSize)); + sb.append(indent + tab + tab + tab + tab); } - sb.append(");" + cr); - sb.append(indent + "}" + cr); + sb.append(");" + CR); + sb.append(indent + "}" + CR); } } } - return sb.toString(); + return sb.toString(); } - + // Methods for generation of code snippets for amqp_methods.h/cpp files - + protected String generateMethodBodyIncludeList(AmqpModel model, int indentSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - - for (String thisClassName : model.classMap.keySet()) + + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "#include \"" + thisClass.name + Utils.firstUpper(method.name) + "Body.h\"" + cr); + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + sb.append(indent + "#include \"" + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body.h\"" + CR); } } - - return sb.toString(); + + return sb.toString(); } - + protected String generateMethodBodyInstances(AmqpModel model, int indentSize) { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - - for (String thisClassName : model.classMap.keySet()) + + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - sb.append(indent + "const " + thisClass.name + Utils.firstUpper(method.name) + "Body " + - Utils.firstLower(thisClass.name) + "_" + method.name + ";" + cr); + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + sb.append(indent + "const " + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body " + + Utils.firstLower(thisClass.getName()) + "_" + method.getName() + ";" + CR); } } - - return sb.toString(); + + return sb.toString(); } - + protected String generateMethodBodyMapEntry(AmqpModel model, int indentSize) - throws AmqpTypeMappingException { String indent = Utils.createSpaces(indentSize); StringBuffer sb = new StringBuffer(); - - for (AmqpVersion version : globalVersionSet) + + for (AmqpVersion version : getVersionSet()) { - for (String thisClassName : model.classMap.keySet()) + for (String thisClassName : model.getClassMap().keySet()) { - AmqpClass thisClass = model.classMap.get(thisClassName); - for (String thisMethodName : thisClass.methodMap.keySet()) + AmqpClass thisClass = model.getClassMap().get(thisClassName); + for (String thisMethodName : thisClass.getMethodMap().keySet()) { - AmqpMethod method = thisClass.methodMap.get(thisMethodName); - String namespace = method.isVersionConsistent(globalVersionSet) ? "" : version.namespace() + "::"; + AmqpMethod method = thisClass.getMethodMap().get(thisMethodName); + String namespace = method.isVersionConsistent(getVersionSet()) ? "" : version.namespace() + "::"; try { - int classOrdinal = thisClass.indexMap.getOrdinal(version); - int methodOrdinal = method.indexMap.getOrdinal(version); - String methodModyClassName = namespace + thisClass.name + Utils.firstUpper(method.name) + "Body"; + int classOrdinal = thisClass.getIndexMap().getOrdinal(version); + int methodOrdinal = method.getIndexMap().getOrdinal(version); + String methodModyClassName = namespace + thisClass.getName() + Utils.firstUpper(method.getName()) + "Body"; sb.append(indent + "insert(std::make_pair(createMapKey(" + classOrdinal + ", " + - methodOrdinal + ", " + version.getMajor() + ", " + version.getMinor() + - "), &createMethodBodyFn<" + methodModyClassName + ">));" + cr); + methodOrdinal + ", " + version.getMajor() + ", " + version.getMinor() + + "), &createMethodBodyFn<" + methodModyClassName + ">));" + CR); } - catch (AmqpTypeMappingException e) {} // ignore + catch (AmqpTypeMappingException e) + { + } // ignore } } } - - return sb.toString(); + + return sb.toString(); } - - + // Helper functions - - private String generateVersionCheck(AmqpVersion version) - { - return "version.equals(" + version.getMajor() + ", " + version.getMinor() + ")"; - } - - private String generateVersionCheck(AmqpVersionSet versionSet) - throws AmqpTypeMappingException - { - StringBuffer sb = new StringBuffer(); - for (AmqpVersion v : versionSet) - { - if (!v.equals(versionSet.first())) - sb.append(" || "); - if (versionSet.size() > 1) - sb.append("("); - sb.append("version.equals(" + v.getMajor() + ", " + v.getMinor() + ")"); - if (versionSet.size() > 1) - sb.append(")"); - } - return sb.toString(); - } - - private String parseForReservedWords(String name, String context) - { - for (String cppReservedWord : cppReservedWords) - if (name.compareTo(cppReservedWord) == 0) - { + + private String generateVersionCheck(AmqpVersion version) + { + return "version.equals(" + version.getMajor() + ", " + version.getMinor() + ")"; + } + + private String generateVersionCheck(AmqpVersionSet versionSet) + { + StringBuffer sb = new StringBuffer(); + for (AmqpVersion v : versionSet) + { + if (!v.equals(versionSet.first())) + { + sb.append(" || "); + } + if (versionSet.size() > 1) + { + sb.append("("); + } + sb.append("version.equals(" + v.getMajor() + ", " + v.getMinor() + ")"); + if (versionSet.size() > 1) + { + sb.append(")"); + } + } + return sb.toString(); + } + + private String parseForReservedWords(String name, String context) + { + for (String cppReservedWord : cppReservedWords) + { + if (name.compareTo(cppReservedWord) == 0) + { if (!quietFlag) { System.out.println("WARNING: " + (context == null ? "" : context + ": ") + - "Found XML method \"" + name + "\", which is a C++ reserved word. " + - "Changing generated name to \"" + name + "_\"."); + "Found XML method \"" + name + "\", which is a C++ reserved word. " + + "Changing generated name to \"" + name + "_\"."); } - return name + "_"; - } - - for (String cppCommonDefine : cppCommonDefines) + return name + "_"; + } + } + + for (String cppCommonDefine : cppCommonDefines) + { if (name.compareTo(cppCommonDefine) == 0) { if (!quietFlag) { System.out.println("WARNING: " + (context == null ? "" : context + ": ") + - "Found XML method \"" + name + "\", which may clash with commonly used defines within C++. " + - "Changing generated name to \"" + name + "_\"."); + "Found XML method \"" + name + "\", which may clash with commonly used defines within C++. " + + "Changing generated name to \"" + name + "_\"."); } return name + "_"; } - - return name; - } - - private String setRef(String codeType) - { - if (codeType.compareTo("string") == 0 || - codeType.compareTo("FieldTable") == 0) - return "const " + codeType + "&"; - return codeType; - } - - private String camelCaseName(String name, boolean upperFirstFlag) - { - StringBuffer ccn = new StringBuffer(); - String[] toks = name.split("[-_.\\ ]"); - for (int i=0; i0) - b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); - ccn.append(b); - } - return ccn.toString(); - } + } + + return name; + } + + private String setRef(String codeType) + { + if (codeType.compareTo("string") == 0 || + codeType.compareTo("FieldTable") == 0) + { + return "const " + codeType + "&"; + } + return codeType; + } + + private String camelCaseName(String name, boolean upperFirstFlag) + { + StringBuffer ccn = new StringBuffer(); + String[] toks = name.split("[-_.\\ ]"); + for (int i = 0; i < toks.length; i++) + { + StringBuffer b = new StringBuffer(toks[i]); + if (upperFirstFlag || i > 0) + { + b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); + } + ccn.append(b); + } + return ccn.toString(); + } + + public static Factory _factoryInstance = new Factory() + { + + public CppGenerator newInstance() + { + return new CppGenerator(); + } + }; + + public static Factory getFactory() + { + return _factoryInstance; + } + + void processModelTemplate(NamedTemplate template, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + public String getNativeType(String type) + { + throw new UnsupportedOperationException(); + } + + public String getEncodingType(String type) + { + throw new UnsupportedOperationException(); + } + } diff --git a/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java b/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java index 3593145db1..d3a7e393ff 100644 --- a/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/DotnetGenerator.java @@ -1,319 +1,361 @@ package org.apache.qpid.gentools; import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.util.TreeMap; public class DotnetGenerator extends Generator { - private class DomainInfo - { - public String type; - public String size; - public String encodeExpression; - public String decodeExpression; - public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression) - { - this.type = domain; - this.size = size; - this.encodeExpression = encodeExpression; - this.decodeExpression = decodeExpression; - } - } - - private static TreeMap 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. + 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 String getNativeType(String type) + { + throw new UnsupportedOperationException(); + } + + public String getEncodingType(String type) + { + throw new UnsupportedOperationException(); + } + + public DotnetGenerator() + { + super(); + // Load .NET type and size maps. + // Adjust or add to these lists as new types are added/defined. + // The char '#' will be replaced by the field variable name (any type). + // The char '~' will be replaced by the compacted bit array size (type bit only). + // TODO: I have left a copy of the Java typeMap here - replace with appropriate .NET values. + typeMap.put("bit", new DomainInfo( + "boolean", // .NET code type + "~", // size + "EncodingUtils.writeBooleans(buffer, #)", // encode expression + "# = EncodingUtils.readBooleans(buffer)")); // decode expression + typeMap.put("content", new DomainInfo( + "Content", // .NET code type + "EncodingUtils.encodedContentLength(#)", // size + "EncodingUtils.writeContentBytes(buffer, #)", // encode expression + "# = EncodingUtils.readContent(buffer)")); // decode expression + typeMap.put("long", new DomainInfo( + "long", // .NET code type + "4", // size + "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression + "# = buffer.getUnsignedInt()")); // decode expression + typeMap.put("longlong", new DomainInfo( + "long", // .NET code type + "8", // size + "buffer.putLong(#)", // encode expression + "# = buffer.getLong()")); // decode expression + typeMap.put("longstr", new DomainInfo( + "byte[]", // .NET code type + "EncodingUtils.encodedLongstrLength(#)", // size + "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression + "# = EncodingUtils.readLongstr(buffer)")); // decode expression + typeMap.put("octet", new DomainInfo( + "short", // .NET code type + "1", // size + "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression + "# = buffer.getUnsigned()")); // decode expression + typeMap.put("short", new DomainInfo( + "int", // .NET code type + "2", // size + "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression + "# = buffer.getUnsignedShort()")); // decode expression + typeMap.put("shortstr", new DomainInfo( + "AMQShortString", // .NET code type + "EncodingUtils.encodedShortStringLength(#)", // size + "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression + "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression + typeMap.put("table", new DomainInfo( + "FieldTable", // .NET code type + "EncodingUtils.encodedFieldTableLength(#)", // size + "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression + "# = EncodingUtils.readFieldTable(buffer)")); // decode expression + typeMap.put("timestamp", new DomainInfo( + "long", // .NET code type + "8", // size + "EncodingUtils.writeTimestamp(buffer, #)", // encode expression + "# = EncodingUtils.readTimestamp(buffer)")); // decode expression + } + + void processModelTemplate(NamedTemplate template, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected String prepareFilename(String filenameTemplate, + AmqpClass thisClass, AmqpMethod method, AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(filenameTemplate); + if (thisClass != null) + { + replaceToken(sb, "${CLASS}", thisClass.getName()); + } + if (method != null) + { + replaceToken(sb, "${METHOD}", method.getName()); + } + if (field != null) + { + replaceToken(sb, "${FIELD}", field.getName()); + } + return sb.toString(); + } + + @Override + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, + int listMarkerEndIndex, AmqpModel model, AmqpVersion version) + throws AmqpTemplateException, AmqpTypeMappingException + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + // TODO: Add in tokens and calls to their corresponding generator methods here... + if (token.compareTo("${??????????}") == 0) + { + codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. // codeSnippet = generateRegistry(model, 8, 4); - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processConstantList(StringBuffer sb, - int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) throws AmqpTemplateException, - AmqpTypeMappingException - { + } + + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processConstantList(StringBuffer sb, + int listMarkerStartIndex, int listMarkerEndIndex, + AmqpConstantSet constantSet) throws AmqpTemplateException, + AmqpTypeMappingException + { String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr int tokStart = tline.indexOf('$'); String token = tline.substring(tokStart).trim(); sb.delete(listMarkerStartIndex, lend); - // TODO: Add in tokens and calls to their corresponding generator methods here... + // TODO: Add in tokens and calls to their corresponding generator methods here... if (token.compareTo("${??????????}") == 0) { - codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. + codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. // codeSnippet = generateConstantGetMethods(constantSet, 4, 4); } - + else // Oops! { throw new AmqpTemplateException("Template token " + token + " unknown."); } sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, - int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version) - throws AmqpTypeMappingException, AmqpTemplateException, - IllegalAccessException, InvocationTargetException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // TODO: Add in tokens and calls to their corresponding generator methods here... - if (token.compareTo("${??????????}") == 0) - { - codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. + } + + @Override + protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, + int listMarkerEndIndex, AmqpFieldMap fieldMap, AmqpVersion version) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + // TODO: Add in tokens and calls to their corresponding generator methods here... + if (token.compareTo("${??????????}") == 0) + { + codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. // codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, // mangledDeclarationGenerateMethod, 4, 4, this); - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, - int listMarkerEndIndex, AmqpClass thisClass) - throws AmqpTemplateException, AmqpTypeMappingException - { - String codeSnippet; - int lend = sb.indexOf(cr, listMarkerStartIndex) + 1; // Include cr at end of line - String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr - int tokStart = tline.indexOf('$'); - String token = tline.substring(tokStart).trim(); - sb.delete(listMarkerStartIndex, lend); - - // TODO: Add in tokens and calls to their corresponding generator methods here... - if (token.compareTo("${??????????}") == 0) - { - codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. - } - - else // Oops! - { - throw new AmqpTemplateException("Template token " + token + " unknown."); - } - sb.insert(listMarkerStartIndex, codeSnippet); - } - - @Override - protected void processTemplateA(String[] template) throws IOException, - AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - processTemplateD(template, null, null, null); - } - - @Override - protected void processTemplateB(String[] template, AmqpClass thisClass) - throws IOException, AmqpTemplateException, - AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - processTemplateD(template, thisClass, null, null); - } - - @Override - protected void processTemplateC(String[] template, AmqpClass thisClass, - AmqpMethod method) throws IOException, AmqpTemplateException, - AmqpTypeMappingException, IllegalAccessException, - InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - processTemplateD(template, thisClass, method, null); - } - - @Override - protected void processTemplateD(String[] template, AmqpClass thisClass, - AmqpMethod method, AmqpField field) throws IOException, - AmqpTemplateException, AmqpTypeMappingException, - IllegalAccessException, InvocationTargetException - { - // I've put in the Java model here - this can be changed if a different pattern is required. - StringBuffer sb = new StringBuffer(template[1]); - String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field); - try { processAllLists(sb, thisClass, method, null); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + template[templateFileNameIndex] + ": " + e.getMessage()); - } - try { processAllTokens(sb, thisClass, method, field, null); } - catch (AmqpTemplateException e) - { - System.out.println("WARNING: " + template[templateFileNameIndex] + ": " + e.getMessage()); - } - writeTargetFile(sb, new File(genDir + Utils.fileSeparator + filename)); - generatedFileCounter ++; - } - - @Override - protected String processToken(String token, AmqpClass thisClass, - AmqpMethod method, AmqpField field, AmqpVersion version) - throws AmqpTemplateException, AmqpTypeMappingException - { - // TODO Auto-generated method stub - return null; - } - - public String getDomainType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - return globalDomainMap.getDomainType(domainName, version); - } - - public String getGeneratedType(String domainName, AmqpVersion version) - throws AmqpTypeMappingException - { - String domainType = globalDomainMap.getDomainType(domainName, version); - if (domainType == null) + } + + else // Oops! { - throw new AmqpTypeMappingException("Domain type \"" + domainName + - "\" not found in Java typemap."); + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, + int listMarkerEndIndex, AmqpClass thisClass) + throws AmqpTemplateException, AmqpTypeMappingException + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + // TODO: Add in tokens and calls to their corresponding generator methods here... + if (token.compareTo("${??????????}") == 0) + { + codeSnippet = token; // This is a stub to get the compile working - remove when gen method is present. + } + + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processModelTemplate(NamedTemplate template) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + processTemplate(template, null, null, null, null); + } + + @Override + protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + processTemplate(template, thisClass, null, null, null); + } + + @Override + protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + processTemplate(template, thisClass, method, null, null); + } + + @Override + protected void processTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version) + { + // I've put in the Java model here - this can be changed if a different pattern is required. + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version); + try + { + processAllLists(sb, thisClass, method, null); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + template.getName() + ": " + e.getMessage()); + } + try + { + processAllTokens(sb, thisClass, method, field, null); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + template.getName() + ": " + e.getMessage()); + } + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + @Override + protected String processToken(String token, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version) + throws AmqpTemplateException, AmqpTypeMappingException + { + // TODO Auto-generated method stub + return null; + } + + public String getGeneratedType(String domainName, AmqpVersion version) + throws AmqpTypeMappingException + { + String domainType = getDomainType(domainName, version); + if (domainType == null) + { + throw new AmqpTypeMappingException("Domain type \"" + domainName + + "\" not found in Java typemap."); } DomainInfo info = typeMap.get(domainType); if (info == null) { throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); } - return info.type; - } - - public String prepareClassName(String className) - { - return camelCaseName(className, true); - } - - public String prepareDomainName(String domainName) - { - return camelCaseName(domainName, false); - } - - public String prepareMethodName(String methodName) - { - return camelCaseName(methodName, false); - } - - private String camelCaseName(String name, boolean upperFirstFlag) - { - StringBuffer ccn = new StringBuffer(); - String[] toks = name.split("[-_.\\ ]"); - for (int i=0; i0) - b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); - ccn.append(b); - } - return ccn.toString(); - } + return info.type; + } + + public String prepareClassName(String className) + { + return camelCaseName(className, true); + } + + public String prepareDomainName(String domainName) + { + return camelCaseName(domainName, false); + } + + public String prepareMethodName(String methodName) + { + return camelCaseName(methodName, false); + } + + private String camelCaseName(String name, boolean upperFirstFlag) + { + StringBuffer ccn = new StringBuffer(); + String[] toks = name.split("[-_.\\ ]"); + for (int i = 0; i < toks.length; i++) + { + StringBuffer b = new StringBuffer(toks[i]); + if (upperFirstFlag || i > 0) + { + b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); + } + ccn.append(b); + } + return ccn.toString(); + } + + + public static Factory _factoryInstance = new Factory() + { + + public DotnetGenerator newInstance() + { + return new DotnetGenerator(); + } + }; + + public static Factory getFactory() + { + return _factoryInstance; + } + } diff --git a/gentools/src/org/apache/qpid/gentools/Generator.java b/gentools/src/org/apache/qpid/gentools/Generator.java index e7ccd64fbe..ccf61bfbce 100644 --- a/gentools/src/org/apache/qpid/gentools/Generator.java +++ b/gentools/src/org/apache/qpid/gentools/Generator.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -20,410 +20,824 @@ */ package org.apache.qpid.gentools; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; +import org.w3c.dom.Node; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; +import java.io.FilenameFilter; import java.io.IOException; import java.io.LineNumberReader; -import java.lang.reflect.InvocationTargetException; +import java.io.StringWriter; import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; public abstract class Generator implements LanguageConverter { - protected static String cr = Utils.lineSeparator; - protected static enum EnumConstOutputTypes { OUTPUT_STRING, OUTPUT_INTEGER, OUTPUT_DOUBLE; }; - - // This string is reproduced in every generated file as a comment - // TODO: Tie the version info into the build system. - protected static final String generatorInfo = "Qpid Gentools v.0.1"; - protected static final int templateFileNameIndex = 0; - protected static final int templateStringIndex = 1; - - protected ArrayList 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; - } - + protected static String CR = Utils.LINE_SEPARATOR; + + + private static final Map FIXED_SIZE_TYPES = new HashMap(); + + static + { + FIXED_SIZE_TYPES.put("bit", 1); + FIXED_SIZE_TYPES.put("bitfield", 1); + FIXED_SIZE_TYPES.put("long", 4); + FIXED_SIZE_TYPES.put("longlong", 8); + FIXED_SIZE_TYPES.put("octet", 1); + FIXED_SIZE_TYPES.put("short", 2); + FIXED_SIZE_TYPES.put("timestamp", 8); + + } + + private String _templateDirectory; + private String _outputDirectory; + + public AmqpDomainMap getDomainMap() + { + return _domainMap; + } + public AmqpConstantSet getConstantSet() { - return globalConstantSet; - } - - public void setModel(AmqpModel model) - { - this.model = model; - } - - public AmqpModel getModel() - { - return model; - } - - public void initializeTemplates(File[] modelTemplateFiles, File[] classTemplatesFiles, - File[] methodTemplatesFiles, File[] fieldTemplatesFiles) - throws FileNotFoundException, IOException - { - if (modelTemplateFiles.length > 0) - { - System.out.println("Model template file(s):"); - for (File mtf : modelTemplateFiles) - { - System.out.println(" " + mtf.getAbsolutePath()); - String template[] = {mtf.getName(), loadTemplate(mtf)}; - modelTemplateList.add(template); - } - } - if (classTemplatesFiles.length > 0) - { - System.out.println("Class template file(s):"); - //for (int c=0; c 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); - } + return _constantSet; + } + + public AmqpModel getModel() + { + return _model; + } + + abstract public String getNativeType(String type); + + abstract public String getEncodingType(String type); + + + + protected static enum EnumConstOutputTypes + { + OUTPUT_STRING, + OUTPUT_INTEGER, + OUTPUT_DOUBLE; + } + + ; + + public static enum TemplateType + { + model("model"), + clazz("class"), + method("method"), + field("field"); + + private final String _name; + + private TemplateType(String name) + { + _name = name; + } + + public String getName() + { + return _name; + } + } + + ; + + + public static interface Factory + { + public X newInstance(); + } + + + protected static final class NamedTemplate + { + private final String _name; + private final String _template; + private final File _file; + + + public NamedTemplate(String relativePath, File templateFile) + { + _file = templateFile; + _name = relativePath + Utils.FILE_SEPARATOR + templateFile.getName(); + + _template = loadTemplate(templateFile); + } + + + public String getName() + { + return _name; + } + + public String getTemplate() + { + return _template; + } + + + public File getFile() + { + return _file; + } + + } + + + private static final String VELOCITY_TEMPLATE_SUFFIX = ".vm"; + private static final String STANDARD_TEMPLATE_SUFFIX = ".tmpl"; + private static FilenameFilter _tmplFileFilter = new FilenameFilter() + { + + public boolean accept(File dir, String name) + { + return name.endsWith(STANDARD_TEMPLATE_SUFFIX) || name.endsWith(VELOCITY_TEMPLATE_SUFFIX); + } + }; + + + // This string is reproduced in every generated file as a comment + // TODO: Tie the version info into the build system. + protected static final String GENERATOR_INFO = "Qpid Gentools v.0.1"; + + + private final Map> _templates = + new EnumMap>(TemplateType.class); + + private final Map> _versionSpecificTemplates = + new EnumMap>(TemplateType.class); + + + private final AmqpVersionSet _versionSet; + + private final AmqpDomainMap _domainMap; + private final Map _versionToDomainMapMap = new HashMap(); + + private final AmqpConstantSet _constantSet; + private final Map _versionToConstantSetMap = new HashMap(); + + + public AmqpVersionSet getVersionSet() + { + return _versionSet; + } + + private final AmqpModel _model; + private final Map _versionToModelMap = new HashMap(); + + protected int generatedFileCounter; + + public Generator() + { + _versionSet = new AmqpVersionSet(); + _model = new AmqpModel(this); + _constantSet = new AmqpConstantSet(this); + _domainMap = new AmqpDomainMap(this); + + generatedFileCounter = 0; + } + +// public final AmqpVersionSet getVersionSet() +// { +// return _versionSet; +// } + + + public void addVersion(AmqpVersion version) + { + _versionSet.add(version); + if (!_versionToModelMap.containsKey(version)) + { + _versionToModelMap.put(version, new AmqpModel(this)); + } + if (!_versionToDomainMapMap.containsKey(version)) + { + _versionToDomainMapMap.put(version, new AmqpDomainMap(this)); + } + if (!_versionToConstantSetMap.containsKey(version)) + { + _versionToConstantSetMap.put(version, new AmqpConstantSet(this)); + } + } + + public int getNumberGeneratedFiles() + { + return generatedFileCounter; + } + +// public AmqpDomainMap getDomainMap() +// { +// return _domainMap; +// } +// +// public AmqpConstantSet getConstantSet() +// { +// return _constantSet; +// } +// +// +// public AmqpModel getModel() +// { +// return _model; +// } + + public void initializeTemplates() throws IOException + { + + for (TemplateType type : EnumSet.allOf(TemplateType.class)) + { + ArrayList typeTemplates = new ArrayList(); + _templates.put(type, typeTemplates); + ArrayList versionSpecificTypeTemplates = new ArrayList(); + _versionSpecificTemplates.put(type, versionSpecificTypeTemplates); + + File templateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName()); + File versionTemplateDirectory = new File(getTemplateDirectory() + Utils.FILE_SEPARATOR + type.getName() + Utils.FILE_SEPARATOR + "version"); + + File[] templateFiles = templateDirectory.listFiles(_tmplFileFilter); + + File[] versionTemplateFiles = new File[0]; + if (versionTemplateDirectory.exists()) + { + versionTemplateFiles = versionTemplateDirectory.listFiles(_tmplFileFilter); + } + + for (File templateFile : templateFiles) + { + System.out.println(type.getName() + " template file(s):"); + System.out.println(" " + templateFile.getCanonicalPath()); + typeTemplates.add(new NamedTemplate(type.getName(), templateFile)); + } + + + for (File versionTemplateFile : versionTemplateFiles) + { + System.out.println(type.getName() + " template file(s):"); + System.out.println(" " + versionTemplateFile.getCanonicalPath()); + versionSpecificTypeTemplates.add(new NamedTemplate(type.getName() + Utils.FILE_SEPARATOR + "version", versionTemplateFile)); + } + + } + } + + public String getTemplateDirectory() + { + return _templateDirectory; + } + + + public void setTemplateDirectory(String templateDirectory) + { + _templateDirectory = templateDirectory; + } + + + public void setOutputDirectory(String outputDirectory) + { + _outputDirectory = outputDirectory; + } + + public void generate() + { + prepareTargetDirectory(new File(_outputDirectory), true); + System.out.println("Generation directory: " + _outputDirectory); + + + processModelTemplates(_templates); + + for (AmqpClass amqpClass : _model.getClassMap().values()) + { + processClassTemplates(_templates, amqpClass); + + for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values()) + { + processMethodTemplates(_templates, amqpClass, amqpMethod); + + for (AmqpField amqpField : amqpMethod.getFieldMap().values()) + { + processFieldTemplates(_templates, amqpClass, amqpMethod, amqpField, null); + } + } + } + + + for (AmqpVersion version : _versionSet) + { + AmqpModel model = _versionToModelMap.get(version); + processModelTemplates(_versionSpecificTemplates, version); + + for (AmqpClass amqpClass : model.getClassMap().values()) + { + processClassTemplates(_versionSpecificTemplates, amqpClass, version); + + for (AmqpMethod amqpMethod : amqpClass.getMethodMap().values()) + { + processMethodTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, version); + + for (AmqpField amqpField : amqpMethod.getFieldMap().values()) + { + processFieldTemplates(_versionSpecificTemplates, amqpClass, amqpMethod, amqpField, version); + } + } + } + + } + } + + private void processMethodTemplates(Map> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version) + { + for (NamedTemplate template : templates.get(TemplateType.method)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,version,amqpClass,amqpMethod,null); + } + else + { + processMethodTemplate(template, amqpClass, amqpMethod); + } + } + + } + + private void processClassTemplates(Map> templates, AmqpClass amqpClass, AmqpVersion version) + { + for (NamedTemplate template : templates.get(TemplateType.clazz)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,version,amqpClass,null,null); + } + else + { + processClassTemplate(template, amqpClass); + } + } + + } + + + private void processModelTemplates(Map> templates, AmqpVersion version) + { + for (NamedTemplate template : templates.get(TemplateType.model)) + { + if (isVelocityTemplate(template)) + { + processModelVelocityTemplate(template, version); + } + else + { + processModelTemplate(template, version); + } + } + } + + abstract void processModelTemplate(NamedTemplate template, AmqpVersion version); + + + protected void processModelTemplates(Map> templates) + { + for (NamedTemplate template : templates.get(TemplateType.model)) + { + if (isVelocityTemplate(template)) + { + processModelVelocityTemplate(template, null); + } + else + { + processModelTemplate(template); + } + } + } + + private boolean isVelocityTemplate(NamedTemplate template) + { + return template.getName().endsWith(VELOCITY_TEMPLATE_SUFFIX); + } + + private void processModelVelocityTemplate(NamedTemplate template, AmqpVersion version) + { + processVelocityTemplate(template,version,null,null,null); + } + + private void processVelocityTemplate(NamedTemplate template, AmqpVersion version, + AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField) + { + + VelocityContext context = new VelocityContext(); + + AmqpModel model = _model; + if(version != null) + { + model = _versionToModelMap.get(version); + } + context.put("model", model); + context.put("generator", GENERATOR_INFO); + + if (version != null) + { + context.put("version", version); + } + if(amqpClass != null) + { + context.put("amqpClass", amqpClass); + } + + if(amqpClass != null) + { + context.put("amqpMethod", amqpMethod); + } + + + StringWriter sw = new StringWriter(); + + + try + { + Template velocityTemplate = Velocity.getTemplate(template.getName()); + velocityTemplate.merge(context, sw); + String filename = String.valueOf(context.get("filename")); + FileWriter outputFileWriter = new FileWriter(getOutputDirectory() + Utils.FILE_SEPARATOR + filename); + outputFileWriter.append(sw.toString()); + outputFileWriter.close(); + + } + catch (Exception e) + { + e.printStackTrace(); + } + + + } + + + protected void processClassTemplates(Map> templates, AmqpClass amqpClass) + { + for (NamedTemplate template : templates.get(TemplateType.clazz)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,null,amqpClass,null,null); + } + else + { + processClassTemplate(template, amqpClass); + } + } + } + + protected void processMethodTemplates(Map> templates, AmqpClass amqpClass, AmqpMethod amqpMethod) + { + for (NamedTemplate template : templates.get(TemplateType.method)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,null,amqpClass,amqpMethod,null); + } + else + { + processMethodTemplate(template, amqpClass, amqpMethod); + } + } + } + + + protected void processFieldTemplates(Map> templates, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion amqpVersion) + { + for (NamedTemplate template : templates.get(TemplateType.field)) + { + if(isVelocityTemplate(template)) + { + processVelocityTemplate(template,amqpVersion,amqpClass,amqpMethod,amqpField); + } + else + { + processTemplate(template, amqpClass, amqpMethod, amqpField, amqpVersion); + } + } + } + + + protected void processVersionList(StringBuffer sb, int tokStart, int tokEnd) + { + int lend = sb.indexOf(Utils.LINE_SEPARATOR, tokStart) + 1; // Include cr at end of line + String tline = sb.substring(tokEnd, lend); // Line excluding line marker, including cr + sb.delete(tokStart, lend); + + for (AmqpVersion v : _versionSet) + { + // Insert copy of target line + StringBuffer isb = new StringBuffer(tline); + if (isb.indexOf("${protocol-version-list-entry}") >= 0) + { + String versionListEntry = " { ${major}, ${minor} }" + + (v.equals(_versionSet.last()) ? "" : ","); + replaceToken(isb, "${protocol-version-list-entry}", String.valueOf(versionListEntry)); + } + if (isb.indexOf("${major}") >= 0) + { + replaceToken(isb, "${major}", String.valueOf(v.getMajor())); + } + if (isb.indexOf("${minor}") >= 0) + { + replaceToken(isb, "${minor}", String.valueOf(v.getMinor())); + } + sb.insert(tokStart, isb.toString()); + tokStart += isb.length(); + } + } + + // Helper functions common to all generators + + protected static void prepareTargetDirectory(File dir, boolean createFlag) + { + if (dir.exists()) + { + if (!dir.isDirectory()) + { + throw new TargetDirectoryException("\"" + dir.getAbsolutePath() + + "\" exists, but is not a directory."); + } + } + else if (createFlag) // Create dir + { + if (!dir.mkdirs()) + { + throw new TargetDirectoryException("Unable to create directory \"" + + dir.getAbsolutePath() + "\"."); + } + } + else + { + throw new TargetDirectoryException("Directory \"" + dir.getAbsolutePath() + + "\" not found."); + } + + } + + protected void processAllLists(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpVersion version) + { + AmqpModel model = (version == null) ? _model : _versionToModelMap.get(version); + + + int lstart = sb.indexOf("%{"); + while (lstart != -1) + { + int lend = sb.indexOf("}", lstart + 2); + if (lend > 0) + { + String listToken = sb.substring(lstart + 2, lend); + if (listToken.compareTo("VLIST") == 0) + { + processVersionList(sb, lstart, lend + 1); + } + else if (listToken.compareTo("CLIST") == 0) + { + processClassList(sb, lstart, lend + 1, model, version); + } + else if (listToken.compareTo("MLIST") == 0) + { + processMethodList(sb, lstart, lend + 1, thisClass); + } + else if (listToken.compareTo("FLIST") == 0) + { + // Pass the FieldMap from either a class or a method. + // If this is called from a class-level template, we assume that the + // class field list is required. In this case, method will be null. + processFieldList(sb, lstart, lend + 1, + (method == null ? thisClass.getFieldMap() : method.getFieldMap()), + version); + } else if (listToken.compareTo("TLIST") == 0) { - processConstantList(sb, lstart, lend + 1, globalConstantSet); + processConstantList(sb, lstart, lend + 1, _constantSet); + } + else + { + throw new AmqpTemplateException("Unknown list token \"%{" + listToken + + "}\" found in template at index " + lstart + "."); } - 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(); - } + } + lstart = sb.indexOf("%{", lstart + 1); + } + } + + protected void processAllTokens(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) + { + int lstart = sb.indexOf("${"); + while (lstart != -1) + { + int lend = sb.indexOf("}", lstart + 2); + if (lend > 0) + { + String token = sb.substring(lstart, lend + 1); + replaceToken(sb, lstart, token, processToken(token, thisClass, method, field, version)); + } + lstart = sb.indexOf("${", lstart); + } + } + + protected static void writeTargetFile(StringBuffer sb, File f) + { + try + { + f.getParentFile().mkdirs(); + FileWriter fw = new FileWriter(f); + fw.write(sb.toString().toCharArray()); + fw.flush(); + fw.close(); + } + catch (IOException e) + { + throw new AmqpTemplateException(e.getMessage()); + } + } + + + protected static String getTemplateFileName(StringBuffer sb) + { + if (sb.charAt(0) != '&') + { + throw new AmqpTemplateException("No filename marker &{filename} found at start of template."); + } + int cr = sb.indexOf(Utils.LINE_SEPARATOR); + if (cr < 0) + { + throw new AmqpTemplateException("Bad template structure - unable to find first line."); + } + String fileName = sb.substring(2, cr - 1); + sb.delete(0, cr + 1); + return fileName; + } + + protected static void replaceToken(StringBuffer sb, String token, String replacement) + { + replaceToken(sb, 0, token, replacement); + } + + protected static void replaceToken(StringBuffer sb, int index, String token, String replacement) + { + if (replacement != null) + { + int start = sb.indexOf(token, index); + if (start != -1) + { + int len = token.length(); + // Find first letter in token and determine if it is capitalized + char firstTokenLetter = getFirstLetter(token); + if (firstTokenLetter != 0 && Character.isUpperCase(firstTokenLetter)) + { + sb.replace(start, start + len, Utils.firstUpper(replacement)); + } + else + { + sb.replace(start, start + len, replacement); + } + } + } + } + + private static char getFirstLetter(String str) + { + int len = str.length(); + int index = 0; + char tokChar = str.charAt(index); + while (!Character.isLetter(tokChar) && index < len - 1) + { + tokChar = str.charAt(++index); + } + if (Character.isLetter(tokChar)) + { + return tokChar; + } + return 0; + } + + private static String loadTemplate(File f) + { + try + { + StringBuffer sb = new StringBuffer(); + FileReader fr = new FileReader(f); + LineNumberReader lnr = new LineNumberReader(fr); + String line = lnr.readLine(); + while (line != null) + { + + sb.append(line); + sb.append(Utils.LINE_SEPARATOR); + + line = lnr.readLine(); + } + lnr.close(); + fr.close(); + return sb.toString(); + } + catch (FileNotFoundException e) + { + throw new AmqpTemplateException("File not found: " + e.getMessage()); + } + catch (IOException e) + { + throw new AmqpTemplateException("IOException: " + e.getMessage()); + } + } + + public String getDomainType(String domainName, AmqpVersion version) + { + if (version == null) + { + version = _versionSet.first(); + } + return getDomainMap().getDomainType(domainName, version); + } + + + public void addFromNode(Node amqpNode, AmqpVersion version) + { + // 1c. Extract domains + getConstantSet().addFromNode(amqpNode, 0, version); + _versionToConstantSetMap.get(version).addFromNode(amqpNode, 0, version); + + // 1d. Extract domains + getDomainMap().addFromNode(amqpNode, 0, version); + _versionToDomainMapMap.get(version).addFromNode(amqpNode, 0, version); + + // 1e. Extract class/method/field heirarchy + getModel().addFromNode(amqpNode, 0, version); + _versionToModelMap.get(version).addFromNode(amqpNode, 0, version); + } + + + public String getOutputDirectory() + { + return _outputDirectory; + } + + public String prepareConstantName(String constantName) + { + return prepareDomainName(constantName); + } + + + public boolean isFixedSizeType(String type) + { + return FIXED_SIZE_TYPES.containsKey(type); + } + + + public int getTypeSize(String type) + { + return FIXED_SIZE_TYPES.get(type); + } + + + + // Model-level template processing + abstract protected void processModelTemplate(NamedTemplate template); + + // Class-level template processing + abstract protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass); + + // Method-level template processing + abstract protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method); + + // Field-level template processing + abstract protected void processTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version); + + abstract protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version); + + abstract protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version); + + abstract protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model, AmqpVersion version); + + abstract protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpClass thisClass); + + + abstract protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpFieldMap fieldMap, AmqpVersion version); + + abstract protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpConstantSet constantSet); + + } diff --git a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java index 84d06cf204..7730fca1bd 100644 --- a/gentools/src/org/apache/qpid/gentools/JavaGenerator.java +++ b/gentools/src/org/apache/qpid/gentools/JavaGenerator.java @@ -21,1674 +21,1806 @@ package org.apache.qpid.gentools; import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.TreeMap; public class JavaGenerator extends Generator { - // TODO: Move this to parent class - protected static final int FIELD_NAME = 0; - protected static final int FIELD_CODE_TYPE = 1; - - private class DomainInfo - { - public String type; - public String size; - public String encodeExpression; - public String decodeExpression; - public DomainInfo(String domain, String size, String encodeExpression, String decodeExpression) - { - this.type = domain; - this.size = size; - this.encodeExpression = encodeExpression; - this.decodeExpression = decodeExpression; - } - } - - private static TreeMap 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."); + // TODO: Move this to parent class + protected static final int FIELD_NAME = 0; + protected static final int FIELD_CODE_TYPE = 1; + + private class DomainInfo + { + final public String type; + final public String size; + final public String encodingType; + final public String encodeExpression; + final public String decodeExpression; + + public DomainInfo(String domain, String size, String encodingType, String encodeExpression, String decodeExpression) + { + this.type = domain; + this.size = size; + this.encodeExpression = encodeExpression; + this.decodeExpression = decodeExpression; + this.encodingType = encodingType; + } + } + + private static TreeMap typeMap = new TreeMap(); + + // Methods used for generation of code snippets called from the field map parsers + + // Common methods + private final CommandGenerateMethod declarationGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateFieldDeclaration(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + + private MangledGenerateMethod mangledDeclarationGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMangledFieldDeclaration(field, indentSize, tabSize, notLast); + } + }; + + // Methods for MessageBody classes + private CommandGenerateMethod mbGetGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbGetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); //To change body of implemented methods use File | Settings | File Templates. + } + }; + + private MangledGenerateMethod mbMangledGetGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledGetMethod(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod mbParamListGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbParamList(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod mbPassedParamListGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbPassedParamList(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod mbMangledParamListGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledParamList(field, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod mbMangledPassedParamListGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledPassedParamList(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod mbBodyInitGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generateMbBodyInit(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod mbMangledBodyInitGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generateMbMangledBodyInit(field, indentSize, tabSize, notLast); + } + }; + private GenerateMethod mbSizeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldSize(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitSizeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitArrayFieldSize(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod mbEncodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldEncode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitEncodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitFieldEncode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod mbDecodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldDecode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitDecodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitFieldDecode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod mbToStringGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generateMbFieldToString(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod mbBitToStringGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generateMbBitFieldToString(bitFieldList, ordinal, indentSize, tabSize); + } + }; + + // Methods for PropertyContentHeader classes + private CommandGenerateMethod pchClearGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generatePchClearMethod(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod pchMangledClearGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generatePchMangledClearMethod(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod pchGetGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generatePchGetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod pchMangledGetGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generatePchMangledGetMethod(field, indentSize, tabSize, notLast); + } + }; + private CommandGenerateMethod pchSetGenerateMethod = new CommandGenerateMethod() + { + public String generate(String codeType, AmqpField field, AmqpVersionSet versionSet, int indentSize, int tabSize, boolean notLast) + { + return generatePchSetMethod(codeType, field, versionSet, indentSize, tabSize, notLast); + } + }; + private MangledGenerateMethod pchMangledSetGenerateMethod = new MangledGenerateMethod() + { + public String generate(AmqpField field, int indentSize, int tabSize, boolean notLast) + { + return generatePchMangledSetMethod(field, indentSize, tabSize, notLast); + } + }; + private GenerateMethod pchSizeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchFieldSize(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitSizeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitArrayFieldSize(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchEncodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchFieldEncode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitEncodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitFieldEncode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchDecodeGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchFieldDecode(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitDecodeGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitFieldDecode(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchGetPropertyFlagsGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchGetPropertyFlags(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitGetPropertyFlagsGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitGetPropertyFlags(bitFieldList, ordinal, indentSize, tabSize); + } + }; + private GenerateMethod pchSetPropertyFlagsGenerateMethod = new GenerateMethod() + { + public String generate(String domainType, String fieldName, int ordinal, int indentSize, int tabSize) + { + return generatePchSetPropertyFlags(domainType, fieldName, ordinal, indentSize, tabSize); + } + }; + private BitFieldGenerateMethod pchBitSetPropertyFlagsGenerateMethod = new BitFieldGenerateMethod() + { + public String generate(List bitFieldList, int ordinal, int indentSize, int tabSize) + { + return generatePchBitSetPropertyFlags(bitFieldList, ordinal, indentSize, tabSize); + } + }; + + + public String getNativeType(String type) + { + return typeMap.get(type).type; + } + + public String getEncodingType(String type) + { + return typeMap.get(type).encodingType; + } + + + public JavaGenerator() + { + super(); + // Load Java type and size maps. + // Adjust or add to these lists as new types are added/defined. + // The char '#' will be replaced by the field variable name (any type). + // The char '~' will be replaced by the compacted bit array size (type bit only). + typeMap.put("bit", new DomainInfo( + "boolean", // Java code type + "~", // size + "Boolean", // Java code type + "EncodingUtils.writeBooleans(buffer, #)", // encode expression + "# = EncodingUtils.readBooleans(buffer)")); // decode expression + typeMap.put("bitfield", new DomainInfo( + "byte", // Java code type + "~", // size + "Bitfield", + "EncodingUtils.writeBooleans(buffer, #)", // encode expression + "# = EncodingUtils.readBooleans(buffer)")); // decode expression + + typeMap.put("content", new DomainInfo( + "Content", // Java code type + "EncodingUtils.encodedContentLength(#)", // size + "Content", // Java code type + "EncodingUtils.writeContentBytes(buffer, #)", // encode expression + "# = EncodingUtils.readContent(buffer)")); // decode expression + typeMap.put("long", new DomainInfo( + "long", // Java code type + "4", // size + "UnsignedInteger", // Java code type + "EncodingUtils.writeUnsignedInteger(buffer, #)", // encode expression + "# = buffer.getUnsignedInt()")); // decode expression + typeMap.put("longlong", new DomainInfo( + "long", // Java code type + "8", // size + "Long", + "buffer.putLong(#)", // encode expression + "# = buffer.getLong()")); // decode expression + typeMap.put("longstr", new DomainInfo( + "byte[]", // Java code type + "EncodingUtils.encodedLongstrLength(#)", // size + "Bytes", + "EncodingUtils.writeLongStringBytes(buffer, #)", // encode expression + "# = EncodingUtils.readLongstr(buffer)")); // decode expression + typeMap.put("octet", new DomainInfo( + "short", // Java code type + "1", // size + "UnsignedByte", + "EncodingUtils.writeUnsignedByte(buffer, #)", // encode expression + "# = buffer.getUnsigned()")); // decode expression + typeMap.put("short", new DomainInfo( + "int", // Java code type + "2", // size + "UnsignedShort", + "EncodingUtils.writeUnsignedShort(buffer, #)", // encode expression + "# = buffer.getUnsignedShort()")); // decode expression + typeMap.put("shortstr", new DomainInfo( + "AMQShortString", // Java code type + "EncodingUtils.encodedShortStringLength(#)", // size + "AMQShortString", // Java code type + "EncodingUtils.writeShortStringBytes(buffer, #)", // encode expression + "# = EncodingUtils.readAMQShortString(buffer)")); // decode expression + typeMap.put("table", new DomainInfo( + "FieldTable", // Java code type + "EncodingUtils.encodedFieldTableLength(#)", // size + "FieldTable", // Java code type + "EncodingUtils.writeFieldTableBytes(buffer, #)", // encode expression + "# = EncodingUtils.readFieldTable(buffer)")); // decode expression + typeMap.put("timestamp", new DomainInfo( + "long", // Java code type + "8", // size + "Timestamp", + "EncodingUtils.writeTimestamp(buffer, #)", // encode expression + "# = EncodingUtils.readTimestamp(buffer)")); // decode expression + } + + // === Start of methods for Interface LanguageConverter === + + public String prepareClassName(String className) + { + return camelCaseName(className, true); + } + + public String prepareMethodName(String methodName) + { + return camelCaseName(methodName, false); + } + + public String prepareDomainName(String domainName) + { + return camelCaseName(domainName, false); + } + + + public String getGeneratedType(String domainName, AmqpVersion version) + { + String domainType = getDomainType(domainName, version); + if (domainType == null) + { + throw new AmqpTypeMappingException("Domain type \"" + domainName + + "\" not found in Java typemap."); } DomainInfo info = typeMap.get(domainType); if (info == null) { - throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); + throw new AmqpTypeMappingException("Unknown domain: \"" + domainType + "\""); + } + return info.type; + } + + // === Abstract methods from class Generator - Java-specific implementations === + + @Override + protected String prepareFilename(String filenameTemplate, AmqpClass thisClass, AmqpMethod method, + AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(filenameTemplate); + if (thisClass != null) + { + replaceToken(sb, "${CLASS}", thisClass.getName()); + } + if (method != null) + { + replaceToken(sb, "${METHOD}", method.getName()); + } + if (field != null) + { + replaceToken(sb, "${FIELD}", field.getName()); + } + if (version != null) + { + replaceToken(sb, "${MAJOR}", String.valueOf(version.getMajor())); + replaceToken(sb, "${MINOR}", String.valueOf(version.getMinor())); + } + return sb.toString(); + } + + @Override + protected void processModelTemplate(NamedTemplate template) + { + processTemplate(template, null, null, null, null); + } + + @Override + protected void processClassTemplate(NamedTemplate template, AmqpClass thisClass) + { + processTemplate(template, thisClass, null, null, + thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null); + } + + @Override + protected void processMethodTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method) + { + processTemplate(template, thisClass, method, null, + thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null); + } + + protected void processFieldTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field) + { + processTemplate(template, thisClass, method, field, + thisClass.getVersionSet().size() == 1 ? thisClass.getVersionSet().first() : null); + } + + @Override + protected void processTemplate(NamedTemplate template, AmqpClass thisClass, + AmqpMethod method, AmqpField field, AmqpVersion version) + { + StringBuffer sb = new StringBuffer(template.getTemplate()); + String filename = prepareFilename(getTemplateFileName(sb), thisClass, method, field, version); + processTemplate(sb, thisClass, method, field, template.getName(), version); + writeTargetFile(sb, new File(getOutputDirectory() + Utils.FILE_SEPARATOR + filename)); + generatedFileCounter++; + } + + protected void processTemplate(StringBuffer sb, AmqpClass thisClass, AmqpMethod method, + AmqpField field, String templateFileName, AmqpVersion version) + { + try + { + processAllLists(sb, thisClass, method, version); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + try + { + processAllTokens(sb, thisClass, method, field, version); + } + catch (AmqpTemplateException e) + { + System.out.println("WARNING: " + templateFileName + ": " + e.getMessage()); + } + } + + @Override + protected String processToken(String token, AmqpClass thisClass, AmqpMethod method, AmqpField field, + AmqpVersion version) + { + if (token.compareTo("${GENERATOR}") == 0) + { + return GENERATOR_INFO; + } + if (token.compareTo("${CLASS}") == 0 && thisClass != null) + { + return thisClass.getName(); + } + if (token.compareTo("${CLASS_ID_INIT}") == 0 && thisClass != null) + { + return generateIndexInitializer("registerClassId", thisClass.getIndexMap(), 8); + } + if (token.compareTo("${METHOD}") == 0 && method != null) + { + return method.getName(); + } + if (token.compareTo("${METHOD_ID_INIT}") == 0 && method != null) + { + return generateIndexInitializer("registerMethodId", method.getIndexMap(), 8); + } + if (token.compareTo("${FIELD}") == 0 && field != null) + { + return field.getName(); + } + + // This token is used only with class or method-level templates + if (token.compareTo("${pch_property_flags_declare}") == 0) + { + return generatePchPropertyFlagsDeclare(); + } + else if (token.compareTo("${pch_property_flags_initializer}") == 0) + { + int mapSize = method == null ? thisClass.getFieldMap().size() : method.getFieldMap().size(); + return generatePchPropertyFlagsInitializer(mapSize); + } + else if (token.compareTo("${pch_compact_property_flags_initializer}") == 0) + { + return generatePchCompactPropertyFlagsInitializer(thisClass, 8, 4); + } + else if (token.compareTo("${pch_compact_property_flags_check}") == 0) + { + return generatePchCompactPropertyFlagsCheck(thisClass, 8, 4); + } + + // Oops! + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + @Override + protected void processClassList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpModel model, AmqpVersion version) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + if (token.compareTo("${reg_map_put_method}") == 0) + { + codeSnippet = generateRegistry(model, 8, 4); + } + + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processMethodList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpClass thisClass) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + //TODO - we don't have any cases of this (yet). + if (token.compareTo("${???}") == 0) + { + codeSnippet = token; + } + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + sb.insert(listMarkerStartIndex, codeSnippet); + } + + @Override + protected void processFieldList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, + AmqpFieldMap fieldMap, AmqpVersion version) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + // Field declarations - common to MethodBody and PropertyContentHeader classes + if (token.compareTo("${field_declaration}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(declarationGenerateMethod, + mangledDeclarationGenerateMethod, 4, 4, this); + } + + // MethodBody classes + else if (token.compareTo("${mb_field_get_method}") == 0) + { + codeSnippet = fieldMap.parseFieldMap(mbGetGenerateMethod, + mbMangledGetGenerateMethod, 4, 4, this); + } + else if (token.compareTo("${mb_field_parameter_list}") == 0) + { + // 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) + { + String codeSnippet; + int lend = sb.indexOf(CR, listMarkerStartIndex) + 1; // Include cr at end of line + String tline = sb.substring(listMarkerEndIndex, lend); // Line excluding line marker, including cr + int tokStart = tline.indexOf('$'); + String token = tline.substring(tokStart).trim(); + sb.delete(listMarkerStartIndex, lend); + + if (token.compareTo("${const_get_method}") == 0) + { + codeSnippet = generateConstantGetMethods(constantSet, 4, 4); + } + + else // Oops! + { + throw new AmqpTemplateException("Template token " + token + " unknown."); + } + + sb.insert(listMarkerStartIndex, codeSnippet); + } + + // === Protected and private helper functions unique to Java implementation === + + // Methods used for generation of code snippets called from the field map parsers + + // Common methods + + protected String generateFieldDeclaration(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + "public " + codeType + " " + field.getName() + + "; // AMQP version(s): " + versionSet + CR; + } + + protected String generateMangledFieldDeclaration(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(Utils.createSpaces(indentSize) + "public " + codeType + " " + + field.getName() + "_" + (domainCntr++) + "; // AMQP Version(s): " + versionSet + + CR); + } + return sb.toString(); + } + + protected String generateIndexInitializer(String mapName, AmqpOrdinalVersionMap indexMap, int indentSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + + Iterator iItr = indexMap.keySet().iterator(); + while (iItr.hasNext()) + { + int index = iItr.next(); + AmqpVersionSet versionSet = indexMap.get(index); + Iterator vItr = versionSet.iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + sb.append(indent + mapName + "( (byte) " + version.getMajor() + ", (byte) " + version.getMinor() + ", " + index + ");" + CR); + } + } + return sb.toString(); + } + + protected String generateRegistry(AmqpModel model, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + + for (String className : model.getClassMap().keySet()) + { + AmqpClass thisClass = model.getClassMap().get(className); + for (String methodName : thisClass.getMethodMap().keySet()) + { + AmqpMethod method = thisClass.getMethodMap().get(methodName); + for (AmqpVersion version : model.getVersionSet()) + { + // Find class and method index for this version (if it exists) + try + { + int classIndex = findIndex(thisClass.getIndexMap(), version); + int methodIndex = findIndex(method.getIndexMap(), version); + sb.append(indent + "registerMethod(" + CR); + sb.append(indent + tab + "(short)" + classIndex + + ", (short)" + methodIndex + ", (byte)" + version.getMajor() + + ", (byte)" + version.getMinor() + ", " + CR); + sb.append(indent + tab + Utils.firstUpper(thisClass.getName()) + + Utils.firstUpper(method.getName()) + "Body.getFactory());" + CR); + } + catch (Exception e) + { + } // Ignore + } + } + } + return sb.toString(); + } + + protected int findIndex(TreeMap map, AmqpVersion version) + { + 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 IllegalArgumentException("Index not found"); + } + + // Methods for AmqpConstants class + + + public String prepareConstantName(String constantName) + { + return upperCaseName(constantName); + } + + + protected String generateConstantGetMethods(AmqpConstantSet constantSet, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + + for (AmqpConstant constant : constantSet.getContstants()) + { + + if (constant.isVersionConsistent(constantSet.getVersionSet())) + { + // return a constant + String value = constant.firstKey(); + if (Utils.containsOnlyDigits(value)) + { + sb.append(indent + "public static final int " + constant.getName() + " = " + + constant.firstKey() + ";" + CR); + } + else if (Utils.containsOnlyDigitsAndDecimal(value)) + { + sb.append(indent + "public static double " + constant.getName() + " = " + + constant.firstKey() + "; " + CR); + } + else + { + sb.append(indent + "public static String " + constant.getName() + " = " + + constant.firstKey() + "\"; " + CR); + + } + sb.append(CR); + } + else + { + // Return version-specific constant + sb.append(generateVersionDependentGet(constant, "String", "", "\"", "\"", indentSize, tabSize)); + sb.append(generateVersionDependentGet(constant, "int", "AsInt", "", "", indentSize, tabSize)); + sb.append(generateVersionDependentGet(constant, "double", "AsDouble", "(double)", "", indentSize, tabSize)); + sb.append(CR); + } + } + return sb.toString(); + } + + protected String generateVersionDependentGet(AmqpConstant constant, + String methodReturnType, String methodNameSuffix, String returnPrefix, String returnPostfix, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "public static " + methodReturnType + " " + constant.getName() + + methodNameSuffix + "(byte major, byte minor) throws AMQProtocolVersionException" + CR); + sb.append(indent + "{" + CR); + boolean first = true; + Iterator sItr = constant.keySet().iterator(); + while (sItr.hasNext()) + { + String value = sItr.next(); + AmqpVersionSet versionSet = constant.get(value); + sb.append(indent + tab + (first ? "" : "else ") + "if (" + generateVersionCheck(versionSet) + + ")" + CR); + sb.append(indent + tab + "{" + CR); + if (methodReturnType.compareTo("int") == 0 && !Utils.containsOnlyDigits(value)) + { + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); + } + else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(value)) + { + sb.append(generateConstantDeclarationException(constant.getName(), methodReturnType, + indentSize + (2 * tabSize), tabSize)); + } + else + { + sb.append(indent + tab + tab + "return " + returnPrefix + value + returnPostfix + ";" + CR); + } + sb.append(indent + tab + "}" + CR); + first = false; + } + sb.append(indent + tab + "else" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "throw new AMQProtocolVersionException(\"Constant \\\"" + + constant.getName() + "\\\" \" +" + CR); + sb.append(indent + tab + tab + tab + + "\"is undefined for AMQP version \" + major + \"-\" + minor + \".\");" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + "}" + CR); + return sb.toString(); + } + + protected String generateConstantDeclarationException(String name, String methodReturnType, + int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "throw new AMQProtocolVersionException(\"Constant \\\"" + + name + "\\\" \" +" + CR); + sb.append(indent + tab + "\"cannot be converted to type " + methodReturnType + + " for AMQP version \" + major + \"-\" + minor + \".\");" + CR); + return sb.toString(); + } + + // Methods for MessageBody classes + protected String generateMbGetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + "public " + codeType + " get" + + Utils.firstUpper(field.getName()) + "() { return " + field.getName() + "; }" + + CR; + } + + protected String generateMbMangledGetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(CR); + sb.append(indent + "public T get" + Utils.firstUpper(field.getName()) + + "(Class classObj) throws AMQProtocolVersionException" + CR); + sb.append(indent + "{" + CR); + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(indent + tab + "if (classObj.equals(" + codeType + + ".class)) // AMQP Version(s): " + versionSet + CR); + sb.append(indent + tab + tab + "return (T)(Object)" + field.getName() + "_" + + (domainCntr++) + ";" + CR); + } + sb.append(indent + tab + + "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + + CR + " \"field \\\"" + field.getName() + + "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generateMbParamList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + codeType + " " + field.getName() + + (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + CR; + } + + + protected String generateMbPassedParamList(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + field.getName() + + (nextFlag ? "," : "") + " // AMQP version(s): " + versionSet + CR; + } + + + protected String generateMbMangledParamList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(Utils.createSpaces(indentSize) + codeType + " " + field.getName() + "_" + + (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + + versionSet + CR); + } + return sb.toString(); + } + + protected String generateMbMangledPassedParamList(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + sb.append(Utils.createSpaces(indentSize) + field.getName() + "_" + + (domainCntr++) + (nextFlag ? "," : "") + " // AMQP version(s): " + + versionSet + CR); + } + return sb.toString(); + } + + + protected String generateMbBodyInit(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + return Utils.createSpaces(indentSize) + "this." + field.getName() + " = " + field.getName() + + ";" + CR; + } + + protected String generateMbMangledBodyInit(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + StringBuffer sb = new StringBuffer(); + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + dItr.next(); + sb.append(Utils.createSpaces(indentSize) + "this." + field.getName() + "_" + domainCntr + + " = " + field.getName() + "_" + (domainCntr++) + ";" + CR); + } + return sb.toString(); + } + + protected String generateMbFieldSize(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldName) + + "; // " + fieldName + ": " + domainType + CR); + return sb.toString(); + } + + protected String generateMbBitArrayFieldSize(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + int numBytes = ((bitFieldList.size() - 1) / 8) + 1; + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + sb.append(Utils.createSpaces(indentSize) + "size += " + + typeMap.get("bit").size.replaceAll("~", String.valueOf(numBytes)) + + "; // " + comment + CR); + return sb.toString(); + } + + protected String generateMbFieldEncode(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + typeMap.get(domain).encodeExpression.replaceAll("#", fieldName) + + "; // " + fieldName + ": " + domain + CR); + return sb.toString(); + } + + protected String generateMbBitFieldEncode(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + + StringBuilder sb = new StringBuilder(); + int i = 0; + while (i < bitFieldList.size()) + { + + StringBuilder line = new StringBuilder(); + + for (int j = 0; i < bitFieldList.size() && j < 8; i++, j++) + { + if (j != 0) + { + line.append(", "); + } + line.append(bitFieldList.get(i)); + } + + sb.append(indent + + typeMap.get("bit").encodeExpression.replaceAll("#", line.toString()) + ";" + CR); + } + return sb.toString(); + } + + protected String generateMbFieldDecode(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + typeMap.get(domain).decodeExpression.replaceAll("#", fieldName) + + "; // " + fieldName + ": " + domain + CR); + return sb.toString(); + } + + protected String generateMbBitFieldDecode(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + + StringBuilder sb = new StringBuilder(indent); + sb.append("byte packedValue;"); + sb.append(CR); + + // RG HERE! + + int i = 0; + while (i < bitFieldList.size()) + { + sb.append(indent + "packedValue = EncodingUtils.readByte(buffer);" + CR); + + for (int j = 0; i < bitFieldList.size() && j < 8; i++, j++) + { + sb.append(indent + bitFieldList.get(i) + " = ( packedValue & (byte) (1 << " + j + ") ) != 0;" + CR); + } } - return 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); - } + return sb.toString(); + } - @Override - protected void processConstantList(StringBuffer sb, int listMarkerStartIndex, int listMarkerEndIndex, - AmqpConstantSet constantSet) - throws AmqpTemplateException, AmqpTypeMappingException + protected String generateMbFieldToString(String domain, String fieldName, + int ordinal, int indentSize, int tabSize) + { + StringBuffer sb = new StringBuffer(); + sb.append(Utils.createSpaces(indentSize) + + "buf.append(\" " + fieldName + ": \" + " + fieldName + ");" + CR); + return sb.toString(); + } + protected String generateMbBitFieldToString(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < bitFieldList.size(); i++) { - String 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); + String bitFieldName = bitFieldList.get(i); + sb.append(indent + "buf.append(\" " + bitFieldName + ": \" + " + bitFieldName + + ");" + CR); + } + return sb.toString(); + } - if (token.compareTo("${const_get_method}") == 0) + // Methods for PropertyContentHeader classes + + protected String generatePchClearMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + // This is one case where the ordinal info is the only significant factor, + // the domain info plays no part. Defer to the mangled version; the code would be + // identical anyway... + return generatePchMangledClearMethod(field, indentSize, tabSize, nextFlag); + } + + protected String generatePchMangledClearMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "public void clear" + Utils.firstUpper(field.getName()) + + "()" + CR); + sb.append(indent + "{" + CR); + + // If there is more than one ordinal for this field or the ordinal does not + // apply to all known versions, then we need to generate version checks so + // we know which fieldProperty to clear. + if (field.getOrdinalMap().size() == 1 && + field.getOrdinalMap().get(field.getOrdinalMap().firstKey()).size() == field.getVersionSet().size()) { - codeSnippet = generateConstantGetMethods(constantSet, 4, 4); + int ordinal = field.getOrdinalMap().firstKey(); + sb.append(indent + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + "propertyFlags[" + ordinal + "] = false;" + CR); } - - else // Oops! + else { - throw new AmqpTemplateException("Template token " + token + " unknown."); + Iterator oItr = field.getOrdinalMap().keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + AmqpVersionSet versionSet = field.getOrdinalMap().get(ordinal); + sb.append(indent + tab); + if (ordinal != field.getOrdinalMap().firstKey()) + { + sb.append("else "); + } + sb.append("if ("); + sb.append(generateVersionCheck(versionSet)); + sb.append(")" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = false;" + CR); + sb.append(indent + tab + "}" + CR); + } } + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } - sb.insert(listMarkerStartIndex, codeSnippet); + protected String generatePchGetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(indent + "public " + codeType + " get" + + Utils.firstUpper(field.getName()) + "()" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "decodeIfNecessary();" + CR); + sb.append(indent + tab + "return " + field.getName() + ";" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchMangledGetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(indent + "public T get" + + Utils.firstUpper(field.getName()) + + "(Class classObj) throws AMQProtocolVersionException" + CR); + sb.append(indent + "{" + CR); + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) + { + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + sb.append(indent + tab + "if (classObj.equals(" + codeType + + ".class)) // AMQP Version(s): " + versionSet + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "decodeIfNecessary();" + CR); + sb.append(indent + tab + tab + "return (T)(Object)" + field.getName() + "_" + + (domainCntr++) + ";" + CR); + sb.append(indent + tab + "}" + CR); } - - - // === 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(); - - Iterator iItr = indexMap.keySet().iterator(); - while (iItr.hasNext()) - { - int index = iItr.next(); - AmqpVersionSet versionSet = indexMap.get(index); - Iterator vItr = versionSet.iterator(); - while (vItr.hasNext()) - { - AmqpVersion version = vItr.next(); - sb.append(indent + mapName + "( (byte) " + version.getMajor() +", (byte) " + version.getMinor() + ", " + index + ");" + cr); - } - } - return sb.toString(); - } - - protected String generateRegistry(AmqpModel model, int indentSize, int tabSize) - { - String indent = Utils.createSpaces(indentSize); - String tab = Utils.createSpaces(tabSize); - StringBuffer sb = new StringBuffer(); - - for (String className : model.classMap.keySet()) - { - AmqpClass thisClass = model.classMap.get(className); - for (String methodName : thisClass.methodMap.keySet()) - { - AmqpMethod method = thisClass.methodMap.get(methodName); - for (AmqpVersion version : globalVersionSet) - { - // Find class and method index for this version (if it exists) - try - { - int classIndex = findIndex(thisClass.indexMap, version); - int methodIndex = findIndex(method.indexMap, version); - sb.append(indent + "registerMethod(" + cr); - sb.append(indent + tab + "(short)" + classIndex + - ", (short)" + methodIndex + ", (byte)" + version.getMajor() + - ", (byte)" + version.getMinor() + ", " + cr); - sb.append(indent + tab + Utils.firstUpper(thisClass.name) + - Utils.firstUpper(method.name) + "Body.getFactory());" + cr); - } - catch (Exception e) {} // Ignore - } - } - } - return sb.toString(); - } - - protected int findIndex(TreeMap 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 + sb.append(indent + tab + + "throw new AMQProtocolVersionException(\"None of the AMQP versions defines \" +" + + CR + " \"field \\\"" + field.getName() + + "\\\" as domain \\\"\" + classObj.getName() + \"\\\".\");" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchSetMethod(String codeType, AmqpField field, + AmqpVersionSet versionSet, int indentSize, int tabSize, boolean nextFlag) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "public void set" + Utils.firstUpper(field.getName()) + + "(" + codeType + " " + field.getName() + ")" + CR); + sb.append(indent + "{" + CR); + + // If there is more than one ordinal for this field or the ordinal does not + // apply to all known versions, then we need to generate version checks so + // we know which fieldProperty to clear. + if (field.getOrdinalMap().size() == 1 && + field.getOrdinalMap().get(field.getOrdinalMap().firstKey()).size() == field.getVersionSet().size()) + { + int ordinal = field.getOrdinalMap().firstKey(); + sb.append(indent + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + "propertyFlags[" + ordinal + "] = true;" + CR); + sb.append(indent + tab + "this." + field.getName() + " = " + field.getName() + ";" + CR); + } + else + { + Iterator oItr = field.getOrdinalMap().keySet().iterator(); + while (oItr.hasNext()) + { + int ordinal = oItr.next(); + AmqpVersionSet oVersionSet = field.getOrdinalMap().get(ordinal); + sb.append(indent + tab); + if (ordinal != field.getOrdinalMap().firstKey()) + { + sb.append("else "); + } + sb.append("if ("); + sb.append(generateVersionCheck(oVersionSet)); + sb.append(")" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + CR); + sb.append(indent + tab + tab + "this." + field.getName() + " = " + field.getName() + ";" + CR); + sb.append(indent + tab + "}" + CR); + } + } + sb.append(indent + "}" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchMangledSetMethod(AmqpField field, int indentSize, + int tabSize, boolean nextFlag) { String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); StringBuffer sb = new StringBuffer(); - Iterator cItr = constantSet.iterator(); - while (cItr.hasNext()) + + Iterator dItr = field.getDomainMap().keySet().iterator(); + int domainCntr = 0; + while (dItr.hasNext()) { - AmqpConstant constant = cItr.next(); - if (constant.isVersionConsistent(globalVersionSet)) + String domainName = dItr.next(); + AmqpVersionSet versionSet = field.getDomainMap().get(domainName); + String codeType = getGeneratedType(domainName, versionSet.first()); + + // Find ordinal with matching version + AmqpVersionSet commonVersionSet = new AmqpVersionSet(); + Iterator oItr = field.getOrdinalMap().keySet().iterator(); + while (oItr.hasNext()) { - // return a constant - String value = constant.firstKey(); - sb.append(indent + "public static String " + constant.name + "() { return \"" + - constant.firstKey() + "\"; }" + cr); - if (Utils.containsOnlyDigits(value)) + int ordinal = oItr.next(); + AmqpVersionSet oVersionSet = field.getOrdinalMap().get(ordinal); + Iterator vItr = oVersionSet.iterator(); + boolean first = true; + while (vItr.hasNext()) { - sb.append(indent + "public static int " + constant.name + "AsInt() { return " + - constant.firstKey() + "; }" + cr); + AmqpVersion thisVersion = vItr.next(); + if (versionSet.contains(thisVersion)) + { + commonVersionSet.add(thisVersion); + } } - if (Utils.containsOnlyDigitsAndDecimal(value)) + if (!commonVersionSet.isEmpty()) { - sb.append(indent + "public static double " + constant.name + "AsDouble() { return (double)" + - constant.firstKey() + "; }" + cr); + sb.append(indent + "public void set" + Utils.firstUpper(field.getName()) + + "(" + codeType + " " + field.getName() + ")" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab); + if (!first) + { + sb.append("else "); + } + sb.append("if ("); + sb.append(generateVersionCheck(commonVersionSet)); + sb.append(")" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "clearEncodedForm();" + CR); + sb.append(indent + tab + tab + "propertyFlags[" + ordinal + "] = true;" + CR); + sb.append(indent + tab + tab + "this." + field.getName() + "_" + (domainCntr++) + + " = " + field.getName() + ";" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + "}" + CR); + sb.append(CR); + first = false; } - sb.append(cr); } - else + } + return sb.toString(); + } + + protected String generatePchFieldSize(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(indent + "if (propertyFlags[" + ordinal + "]) // " + + fieldName + ": " + domainType + CR); + sb.append(indent + Utils.createSpaces(tabSize) + "size += " + + typeMap.get(domainType).size.replaceAll("#", fieldName) + ";" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitArrayFieldSize(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + StringBuffer sb = new StringBuffer(); + + if (bitFieldList.size() == 1) // single bit + { + sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + comment + CR); + sb.append(indent + tab + "size += " + + typeMap.get("bit").size.replaceAll("~", "1") + ";" + CR); + } + else // multiple bits - up to 8 are combined into one byte + { + String bitCntrName = "bitCntr_" + ordinal; + int startOrdinal = ordinal - bitFieldList.size(); + sb.append(indent + "// " + comment + CR); + sb.append(indent + "int " + bitCntrName + " = 0;" + CR); + sb.append(indent + "for (int i=" + startOrdinal + "; i<" + ordinal + "; i++)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + bitCntrName + "++;" + CR); + sb.append(indent + "}" + CR); + sb.append(indent + "size += " + + typeMap.get("bit").size.replaceAll("~", bitCntrName + + " > 0 ? ((" + bitCntrName + " - 1) / 8) + 1 : 0") + ";" + CR); + } + sb.append(CR); + return sb.toString(); + } + + protected String generatePchFieldEncode(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + + domainType + CR); + sb.append(indent + Utils.createSpaces(tabSize) + + typeMap.get(domainType).encodeExpression.replaceAll("#", fieldName) + ";" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitFieldEncode(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + String comment = bitFieldList.size() == 1 ? + bitFieldList.get(0) + ": bit" : + "Combinded bits: " + bitFieldList; + StringBuffer sb = new StringBuffer(); + + if (bitFieldList.size() == 1) // single bit + { + sb.append(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + + bitFieldList.get(0) + ": bit" + CR); + sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#", + "new boolean[] {" + bitFieldList.get(0) + "}") + ";" + CR); + } + else // multiple bits - up to 8 are combined into one byte + { + int startOrdinal = ordinal - bitFieldList.size(); + String bitCntrName = "bitCntr" + startOrdinal; + sb.append(indent + "// " + comment + CR); + sb.append(indent + "int " + bitCntrName + " = 0;" + CR); + sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + bitCntrName + "++;" + CR); + sb.append(indent + "}" + CR); + sb.append(indent + "if (" + bitCntrName + " > 0) // Are any of the property bits set?" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "boolean[] fullBitArray = new boolean[] { "); + for (int i = 0; i < bitFieldList.size(); i++) { - // 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(); + if (i != 0) + { + sb.append(", "); + } + sb.append(bitFieldList.get(i)); + } + sb.append(" };" + CR); + sb.append(indent + tab + "boolean[] flaggedBitArray = new boolean[" + bitCntrName + + "];" + CR); + sb.append(indent + tab + bitCntrName + " = 0;" + CR); + sb.append(indent + tab + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + + "; i++)" + CR); + sb.append(indent + tab + "{" + CR); + sb.append(indent + tab + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + tab + "flaggedBitArray[" + bitCntrName + + "++] = fullBitArray[i];" + CR); + sb.append(indent + tab + "}" + CR); + sb.append(indent + tab + typeMap.get("bit").encodeExpression.replaceAll("#", + "flaggedBitArray") + ";" + CR); + sb.append(indent + "}" + CR); + } + sb.append(CR); + return sb.toString(); } - - protected String generateVersionDependentGet(AmqpConstant constant, - String methodReturnType, String methodNameSuffix, String returnPrefix, String returnPostfix, - int indentSize, int tabSize) - throws AmqpTypeMappingException + + protected String generatePchFieldDecode(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + + domainType + CR); + sb.append(indent + Utils.createSpaces(tabSize) + + typeMap.get(domainType).decodeExpression.replaceAll("#", fieldName) + ";" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitFieldDecode(List 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(); - 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()) + + if (bitFieldList.size() == 1) // single bit { - 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(indent + "if (propertyFlags[" + (ordinal - 1) + "]) // " + + bitFieldList.get(0) + ": bit" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#", + "boolean[] flaggedBitArray") + ";" + CR); + sb.append(indent + tab + bitFieldList.get(0) + " = flaggedBitArray[0];" + CR); + sb.append(indent + "}" + CR); + } + else // multiple bits - up to 8 are combined into one byte + { + int startOrdinal = ordinal - bitFieldList.size(); + String bitCntr = "bitCntr" + startOrdinal; + sb.append(indent + "// " + comment + CR); + sb.append(indent + "int " + bitCntr + " = 0;" + CR); + sb.append(indent + "for (int i=" + startOrdinal + "; i<=" + (ordinal - 1) + "; i++)" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + "if (propertyFlags[i])" + CR); + sb.append(indent + tab + tab + bitCntr + "++;" + CR); + sb.append(indent + "}" + CR); + sb.append(indent + "if (" + bitCntr + " > 0) // Are any of the property bits set?" + CR); + sb.append(indent + "{" + CR); + sb.append(indent + tab + typeMap.get("bit").decodeExpression.replaceAll("#", + "boolean[] flaggedBitArray") + ";" + CR); + sb.append(indent + tab + bitCntr + " = 0;" + CR); + for (int i = 0; i < bitFieldList.size(); i++) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append(indent + tab + "if (propertyFlags[" + (startOrdinal + i) + "])" + CR); + sb.append(indent + tab + tab + bitFieldList.get(i) + " = flaggedBitArray[" + + bitCntr + "++];" + CR); } - else if (methodReturnType.compareTo("double") == 0 && !Utils.containsOnlyDigitsAndDecimal(value)) + sb.append(indent + "}" + CR); + } + + sb.append(CR); + return sb.toString(); + } + + protected String generatePchGetPropertyFlags(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + int word = ordinal / 15; + int bit = 15 - (ordinal % 15); + sb.append(indent + "if (propertyFlags[" + ordinal + "]) // " + fieldName + ": " + + domainType + CR); + sb.append(indent + tab + "compactPropertyFlags[" + word + "] |= (1 << " + + bit + ");" + CR); + sb.append(CR); + return sb.toString(); + } + + protected String generatePchBitGetPropertyFlags(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + int startOrdinal = ordinal - bitFieldList.size(); + + for (int i = 0; i < bitFieldList.size(); i++) + { + int thisOrdinal = startOrdinal + i; + int word = thisOrdinal / 15; + int bit = 15 - (thisOrdinal % 15); + sb.append(indent + "if (propertyFlags[" + thisOrdinal + "])" + CR); + sb.append(indent + tab + "compactPropertyFlags[" + word + + "] |= (1 << " + bit + ");" + CR); + } + + sb.append(CR); + return sb.toString(); + } + + protected String generatePchSetPropertyFlags(String domainType, String fieldName, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + int word = ordinal / 15; + int bit = 15 - (ordinal % 15); + sb.append(indent + "propertyFlags[" + ordinal + "] = (compactPropertyFlags[" + + word + "] & (1 << " + bit + ")) > 0;" + CR); + return sb.toString(); + } + + protected String generatePchBitSetPropertyFlags(List bitFieldList, + int ordinal, int indentSize, int tabSize) + { + String indent = Utils.createSpaces(indentSize); + StringBuffer sb = new StringBuffer(); + int startOrdinal = ordinal - bitFieldList.size(); + + for (int i = 0; i < bitFieldList.size(); i++) + { + int thisOrdinal = startOrdinal + i; + int word = thisOrdinal / 15; + int bit = 15 - (thisOrdinal % 15); + sb.append(indent + "propertyFlags[" + thisOrdinal + "] = (compactPropertyFlags[" + + word + "] & (1 << " + bit + ")) > 0;" + CR); + } + return sb.toString(); + } + + private String generatePchPropertyFlagsDeclare() + { + return "private boolean[] propertyFlags;"; + } + + private String generatePchPropertyFlagsInitializer(int totNumFields) + { + return "propertyFlags = new boolean[" + totNumFields + "];"; + } + + private String generatePchCompactPropertyFlagsInitializer(AmqpClass thisClass, int indentSize, + int tabSize) + { + String indent = Utils.createSpaces(indentSize); + String tab = Utils.createSpaces(tabSize); + StringBuffer sb = new StringBuffer(); + Iterator vItr = thisClass.getVersionSet().iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + int numBytes = ((thisClass.getFieldMap().getNumFields(version) - 1) / 15) + 1; + + sb.append(indent); + if (!version.equals(thisClass.getVersionSet().first())) { - sb.append(generateConstantDeclarationException(constant.name, methodReturnType, - indentSize + (2*tabSize), tabSize)); + sb.append("else "); } - else + sb.append("if ( major == " + version.getMajor() + " && minor == " + + version.getMinor() + " )" + CR); + sb.append(indent + tab + "compactPropertyFlags = new int[] { "); + for (int i = 0; i < numBytes; i++) { - sb.append(indent + tab + tab + "return " + returnPrefix + value + returnPostfix + ";" + cr); + if (i != 0) + { + sb.append(", "); + } + sb.append(i < numBytes - 1 ? "1" : "0"); // Set the "continue" flag where required } - sb.append(indent + tab + "}" + cr); - first = false; + sb.append(" };" + CR); } - 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(); + return sb.toString(); } - - protected String generateConstantDeclarationException(String name, String methodReturnType, - int indentSize, int tabSize) + + private String generatePchCompactPropertyFlagsCheck(AmqpClass thisClass, 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) + "this." + field.name + "_" + domainCntr + - " = " + field.name + "_" + (domainCntr++) + ";" + cr); - } - return sb.toString(); - } - - protected String generateMbFieldSize(String domainType, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + "size += " + - typeMap.get(domainType).size.replaceAll("#", fieldName) + - "; // " + fieldName + ": " + domainType + cr); - return sb.toString(); - } - - protected String generateMbBitArrayFieldSize(ArrayList 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); - sb.append("byte packedValue;"); - sb.append(cr); - - // RG HERE! - - int i = 0; - while(i < bitFieldList.size()) - { - sb.append(indent + "packedValue = EncodingUtils.readByte(buffer);" + cr); - - for(int j = 0; i < bitFieldList.size() && j < 8; i++, j++) - { - sb.append(indent + bitFieldList.get(i) + " = ( packedValue & (byte) (1 << " + j + ") ) != 0;" + cr); - } - } - return sb.toString(); - } - - protected String generateMbFieldToString(String domain, String fieldName, - int ordinal, int indentSize, int tabSize) - { - StringBuffer sb = new StringBuffer(); - sb.append(Utils.createSpaces(indentSize) + - "buf.append(\" " + fieldName + ": \" + " + fieldName + ");" + cr); - return sb.toString(); - } - - protected String generateMbBitFieldToString(ArrayList 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(); - } + Iterator vItr = thisClass.getVersionSet().iterator(); + while (vItr.hasNext()) + { + AmqpVersion version = vItr.next(); + int numFields = thisClass.getFieldMap().getNumFields(version); + int numBytes = ((numFields - 1) / 15) + 1; + + sb.append(indent); + if (!version.equals(thisClass.getVersionSet().first())) + { + sb.append("else "); + } + sb.append("if ( major == " + version.getMajor() + " && minor == " + + version.getMinor() + " && compactPropertyFlags.length != " + numBytes + " )" + CR); + sb.append(indent + tab + + "throw new AMQProtocolVersionException(\"Property flag array size mismatch:\" +" + CR); + sb.append(indent + tab + tab + "\"(Size found: \" + compactPropertyFlags.length +" + CR); + sb.append(indent + tab + tab + "\") Version " + version + " has " + numFields + + " fields which requires an int array of size " + numBytes + ".\");" + CR); + } + return sb.toString(); + } + + private String generateVersionCheck(AmqpVersionSet v) + { + StringBuffer sb = new StringBuffer(); + AmqpVersion[] versionArray = new AmqpVersion[v.size()]; + v.toArray(versionArray); + for (int i = 0; i < versionArray.length; i++) + { + if (i != 0) + { + sb.append(" || "); + } + if (versionArray.length > 1) + { + sb.append("("); + } + sb.append("major == (byte)" + versionArray[i].getMajor() + " && minor == (byte)" + + versionArray[i].getMinor()); + if (versionArray.length > 1) + { + sb.append(")"); + } + } + return sb.toString(); + } + + private String camelCaseName(String name, boolean upperFirstFlag) + { + StringBuffer ccn = new StringBuffer(); + String[] toks = name.split("[-_.\\ ]"); + for (int i = 0; i < toks.length; i++) + { + StringBuffer b = new StringBuffer(toks[i]); + if (upperFirstFlag || i > 0) + { + b.setCharAt(0, Character.toUpperCase(toks[i].charAt(0))); + } + ccn.append(b); + } + return ccn.toString(); + } + + + private String upperCaseName(String name) + { + StringBuffer ccn = new StringBuffer(); + String[] toks = name.split("[-_.\\ ]"); + for (int i = 0; i < toks.length; i++) + { + if (i != 0) + { + ccn.append('_'); + } + ccn.append(toks[i].toUpperCase()); + + + } + return ccn.toString(); + } + + + public static Factory _factoryInstance = new Factory() + { + + public JavaGenerator newInstance() + { + return new JavaGenerator(); + } + }; + + public static Factory getFactory() + { + return _factoryInstance; + } + + + void processModelTemplate(NamedTemplate template, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processClassTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processMethodTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + void processFieldTemplate(NamedTemplate template, AmqpClass amqpClass, AmqpMethod amqpMethod, AmqpField amqpField, AmqpVersion version) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + } diff --git a/gentools/src/org/apache/qpid/gentools/LanguageConverter.java b/gentools/src/org/apache/qpid/gentools/LanguageConverter.java index cb0a14e3bc..5e692d86e7 100644 --- a/gentools/src/org/apache/qpid/gentools/LanguageConverter.java +++ b/gentools/src/org/apache/qpid/gentools/LanguageConverter.java @@ -22,18 +22,21 @@ package org.apache.qpid.gentools; public interface LanguageConverter { - public void setDomainMap(AmqpDomainMap domainMap); - public AmqpDomainMap getDomainMap(); - - public void setConstantSet(AmqpConstantSet constantSet); - public AmqpConstantSet getConstantSet(); - - public void setModel(AmqpModel model); - public AmqpModel getModel(); - - public String prepareClassName(String className); - public String prepareMethodName(String methodName); - public String prepareDomainName(String domainName); - public String getDomainType(String domainName, AmqpVersion version) throws AmqpTypeMappingException; - public String getGeneratedType(String domainName, AmqpVersion version) throws AmqpTypeMappingException; + +// public AmqpDomainMap getDomainMap(); +// public AmqpConstantSet getConstantSet(); +// public AmqpModel getModel(); + + // + public String prepareClassName(String className); + + public String prepareMethodName(String methodName); + + public String prepareDomainName(String domainName); + + public String getDomainType(String domainName, AmqpVersion version); + + public String getGeneratedType(String domainName, AmqpVersion version); + + public String prepareConstantName(String constantName); } diff --git a/gentools/src/org/apache/qpid/gentools/Main.java b/gentools/src/org/apache/qpid/gentools/Main.java index e8c8a80a26..c0584f7ca7 100644 --- a/gentools/src/org/apache/qpid/gentools/Main.java +++ b/gentools/src/org/apache/qpid/gentools/Main.java @@ -20,143 +20,149 @@ */ package org.apache.qpid.gentools; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import org.apache.velocity.app.Velocity; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Properties; public class Main { - private static final String defaultOutDir = ".." + Utils.fileSeparator + "gen"; - private static final String defaultCppTemplateDir = ".." + Utils.fileSeparator + "templ.cpp"; - private static final String defaultDotnetTemplateDir = ".." + Utils.fileSeparator + "templ.net"; - private static final String defaultJavaTemplateDir = ".." + Utils.fileSeparator + "templ.java"; - - private enum GeneratorLangEnum { CPP, DOTNET, JAVA } - - private DocumentBuilder docBuilder; - private AmqpVersionSet versionSet; - private Generator generator; - private AmqpConstantSet constants; - private AmqpDomainMap domainMap; - private AmqpModel model; - + private static final String DEFAULT_OUTPUT_DIR = ".." + Utils.FILE_SEPARATOR + "gen"; + private static final String DEFAULT_TEMPLATE_DIR_BASE = ".." + Utils.FILE_SEPARATOR; + + private enum GeneratedLanguage + { + CPP(".cpp", CppGenerator.getFactory()), + DOTNET(".net", DotnetGenerator.getFactory()), + JAVA(".java", JavaGenerator.getFactory()); + + private final String _suffix; + private final Generator.Factory _factory; + + + private final String _defaultTemplateDirectory; + + GeneratedLanguage(String suffix, Generator.Factory factory) + { + _suffix = suffix; + _factory = factory; + _defaultTemplateDirectory = DEFAULT_TEMPLATE_DIR_BASE + "templ" + _suffix; + } + + public String getSuffix() + { + return _suffix; + } + + public Generator newGenerator() + { + return _factory.newInstance(); + } + + public String getDefaultTemplateDirectory() + { + return _defaultTemplateDirectory; + } + } + + private Generator generator; + private String outDir; private String tmplDir; - private GeneratorLangEnum generatorLang; + private GeneratedLanguage _generatorLang; private ArrayList xmlFiles; - private File[] modelTemplateFiles; - private File[] classTemplateFiles; - private File[] methodTemplateFiles; - private File[] fieldTemplateFiles; - - public Main() throws ParserConfigurationException - { - docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - versionSet = new AmqpVersionSet(); + + public Main() + { xmlFiles = new ArrayList(); - } - - public void run(String[] args) - throws IOException, - SAXException, - AmqpParseException, - AmqpTypeMappingException, - AmqpTemplateException, - TargetDirectoryException, - IllegalAccessException, - InvocationTargetException - { - modelTemplateFiles = new File[]{}; - classTemplateFiles = new File[]{}; - methodTemplateFiles = new File[]{}; - fieldTemplateFiles = new File[]{}; - + } + + public void run(String[] args) + throws Exception, + SAXException, + AmqpParseException, + AmqpTypeMappingException, + AmqpTemplateException, + TargetDirectoryException, + IllegalAccessException, + InvocationTargetException, ParserConfigurationException + { + // 0. Initialize - outDir = defaultOutDir; + outDir = DEFAULT_OUTPUT_DIR; tmplDir = null; - generatorLang = GeneratorLangEnum.CPP; // Default generation language + _generatorLang = GeneratedLanguage.CPP; // Default generation language xmlFiles.clear(); processArgs(args); - switch (generatorLang) + + if (tmplDir == null) { - case JAVA: - prepareJava(); - break; - case DOTNET: - prepareDotnet(); - break; - default: - prepareCpp(); + tmplDir = _generatorLang.getDefaultTemplateDirectory(); } - if (modelTemplateFiles.length == 0 && classTemplateFiles.length == 0 && - methodTemplateFiles.length == 0 && fieldTemplateFiles.length == 0) - System.err.println(" WARNING: No template files."); - - // 1. Suck in all the XML spec files provided on the command line + + generator = _generatorLang.newGenerator(); + generator.setTemplateDirectory(tmplDir); + generator.setOutputDirectory(outDir); + + // 1. Suck in all the XML spec files provided on the command line analyzeXML(); - - // 2. Load up all templates - try - { - generator.initializeTemplates(modelTemplateFiles, classTemplateFiles, - methodTemplateFiles, fieldTemplateFiles); - } - catch (FileNotFoundException e) - { - System.err.println("Error: Unable to load template file (check -t option on command-line):"); - System.err.println(e.getMessage()); - return; - } - - // 3. Generate output - generator.generate(new File(outDir)); - - System.out.println("Files generated: " + generator.getNumberGeneratedFiles()); - System.out.println("Done."); - } + + Properties p = new Properties(); + p.setProperty("file.resource.loader.path", tmplDir); + + Velocity.init(p); + + // 2. Load up all templates + generator.initializeTemplates(); + + // 3. Generate output + generator.generate(); + + System.out.println("Files generated: " + generator.getNumberGeneratedFiles()); + System.out.println("Done."); + } private void processArgs(String[] args) { // Crude but simple... - for (int i=0; i - -#include -#include -#include - -namespace qpid { -namespace framing { - -class AMQP_ClientProxy; - -class AMQP_ClientOperations -{ -protected: - ProtocolVersion version; - AMQP_ClientOperations() {} - -public: - AMQP_ClientOperations(u_int8_t major, u_int8_t minor) : version(major, minor) {} - AMQP_ClientOperations(ProtocolVersion& version) : version(version) {} - virtual ~AMQP_ClientOperations() {} - - inline u_int8_t getMajor() const { return version.getMajor(); } - inline u_int8_t getMinor() const { return version.getMinor(); } - inline const ProtocolVersion& getVersion() const { return version; } - inline bool isVersion(u_int8_t _major, u_int8_t _minor) const - { - return version.equals(_major, _minor); - } - inline bool isVersion(ProtocolVersion& _version) const - { - return version.equals(_version); - } - - // Include framing constant declarations - #include - - // Inner classes - -%{CLIST} ${coh_inner_class} - - // Method handler get methods - -%{CLIST} ${coh_method_handler_get_method} - -}; /* class AMQP_ClientOperations */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl b/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl deleted file mode 100644 index 8cca6e5cec..0000000000 --- a/gentools/templ.cpp/AMQP_ClientProxy.cpp.tmpl +++ /dev/null @@ -1,52 +0,0 @@ -&{AMQP_ClientProxy.cpp} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#include - -#include -#include -%{MLIST} ${cpc_method_body_include} - -namespace qpid { -namespace framing { - -AMQP_ClientProxy::AMQP_ClientProxy(OutputHandler* out, u_int8_t major, u_int8_t minor) : -%{CLIST} ${cpc_constructor_initializer} - -{} - - // Inner class instance get methods - -%{CLIST} ${cpc_inner_class_get_method} - - // Inner class implementation - -%{CLIST} ${cpc_inner_class_impl} - -} /* namespace framing */ -} /* namespace qpid */ diff --git a/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl b/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl deleted file mode 100644 index 0653ed7186..0000000000 --- a/gentools/templ.cpp/AMQP_ClientProxy.h.tmpl +++ /dev/null @@ -1,75 +0,0 @@ -&{AMQP_ClientProxy.h} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#ifndef qpid_framing_AMQP_ClientProxy__ -#define qpid_framing_AMQP_ClientProxy__ - -#include -#include -#include - -namespace qpid { -namespace framing { - -class AMQP_ClientProxy : public AMQP_ClientOperations -{ -private: - - ProtocolVersion version; - OutputHandler* out; -%{CLIST} ${cph_handler_pointer_defn} - -public: - AMQP_ClientProxy(OutputHandler* out, u_int8_t major, u_int8_t minor); - ProtocolVersion& getProtocolVersion() {return version;} - virtual ~AMQP_ClientProxy() {} - - // Get methods for handlers - -%{CLIST} ${cph_handler_pointer_get_method} - - // Inner class definitions - -%{CLIST} ${cph_inner_class_defn} - -private: - // Inner class instances - -%{CLIST} ${cph_inner_class_instance} - -public: - // Inner class instance get methods - -%{CLIST} ${cph_inner_class_get_method} - -}; /* class AMQP_ClientProxy */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/gentools/templ.cpp/AMQP_Constants.h.tmpl b/gentools/templ.cpp/AMQP_Constants.h.tmpl deleted file mode 100644 index 4631bc8de6..0000000000 --- a/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/gentools/templ.cpp/AMQP_HighestVersion.h.tmpl b/gentools/templ.cpp/AMQP_HighestVersion.h.tmpl deleted file mode 100644 index 9753b454ba..0000000000 --- a/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 - - -namespace qpid { -namespace framing { - -static ProtocolVersion highestProtocolVersion(${hv_latest_major}, ${hv_latest_minor}); - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl b/gentools/templ.cpp/AMQP_MethodVersionMap.cpp.tmpl deleted file mode 100644 index dc2a890c88..0000000000 --- a/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 - -namespace qpid -{ -namespace framing -{ - -AMQP_MethodVersionMap::AMQP_MethodVersionMap() -{ -%{CLIST} ${mc_create_method_body_map_entry} -} - -AMQMethodBody* AMQP_MethodVersionMap::createMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor) -{ - iterator itr = find(createMapKey(classId, methodId, major, minor)); - if (itr == end()) - { - std::stringstream ss; - ss << "Unable to find MethodBody class for classId = " << classId << ", methodId = " << - methodId << ", AMQ protocol version = " << major << "-" << minor << "."; - throw ProtocolVersionException(ss.str()); - } - return (itr->second)(major, minor); -} - -u_int64_t AMQP_MethodVersionMap::createMapKey(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor) -{ - return ((u_int64_t)classId<<48) + ((u_int64_t)methodId<<32) + ((u_int64_t)major<<16) + minor; -} - -} /* namespace framing */ -} /* namespace qpid */ diff --git a/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl b/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl deleted file mode 100644 index c197871d4b..0000000000 --- a/gentools/templ.cpp/AMQP_MethodVersionMap.h.tmpl +++ /dev/null @@ -1,57 +0,0 @@ -&{AMQP_MethodVersionMap.h} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#ifndef qpid_framing_AMQP_MethodVersionMap__ -#define qpid_framing_AMQP_MethodVersionMap__ - -#include -#include - -%{MLIST} ${mc_method_body_include} - -namespace qpid -{ -namespace framing -{ - -template AMQMethodBody* createMethodBodyFn(u_int8_t major, u_int8_t minor) { return new T(major, minor); } -typedef AMQMethodBody* (*fnPtr)(u_int8_t, u_int8_t); - -class AMQP_MethodVersionMap: public std::map -{ -protected: - u_int64_t createMapKey(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor); -public: - AMQP_MethodVersionMap(); - AMQMethodBody* createMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor); -}; - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl b/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl deleted file mode 100644 index e87723667b..0000000000 --- a/gentools/templ.cpp/AMQP_ServerOperations.h.tmpl +++ /dev/null @@ -1,83 +0,0 @@ -&{AMQP_ServerOperations.h} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#ifndef qpid_framing_AMQP_ServerOperations__ -#define qpid_framing_AMQP_ServerOperations__ - -#include - -#include -#include -#include - -namespace qpid { -namespace framing { - -class AMQP_ServerProxy; -class AMQP_ClientProxy; - -class AMQP_ServerOperations -{ -protected: - ProtocolVersion version; - AMQP_ServerOperations() {} - -public: - AMQP_ServerOperations(u_int8_t major, u_int8_t minor) : version(major, minor) {} - AMQP_ServerOperations(ProtocolVersion& version) : version(version) {} - virtual ~AMQP_ServerOperations() {} - - inline u_int8_t getMajor() const { return version.getMajor(); } - inline u_int8_t getMinor() const { return version.getMinor(); } - inline const ProtocolVersion& getVersion() const { return version; } - inline bool isVersion(u_int8_t _major, u_int8_t _minor) const - { - return version.equals(_major, _minor); - } - inline bool isVersion(ProtocolVersion& _version) const - { - return version.equals(_version); - } - - // Include framing constant declarations - #include - - // Inner classes - -%{CLIST} ${soh_inner_class} - - // Method handler get methods - -%{CLIST} ${soh_method_handler_get_method} - -}; /* class AMQP_ServerOperations */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl b/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl deleted file mode 100644 index cce369f98b..0000000000 --- a/gentools/templ.cpp/AMQP_ServerProxy.cpp.tmpl +++ /dev/null @@ -1,51 +0,0 @@ -&{AMQP_ServerProxy.cpp} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#include - -#include -#include -%{MLIST} ${spc_method_body_include} - -namespace qpid { -namespace framing { - -AMQP_ServerProxy::AMQP_ServerProxy(OutputHandler* out, u_int8_t major, u_int8_t minor) : -%{CLIST} ${spc_constructor_initializer} -{} - - // Inner class instance get methods - -%{CLIST} ${spc_inner_class_get_method} - - // Inner class implementation - -%{CLIST} ${spc_inner_class_impl} - -} /* namespace framing */ -} /* namespace qpid */ diff --git a/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl b/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl deleted file mode 100644 index fab29f2c60..0000000000 --- a/gentools/templ.cpp/AMQP_ServerProxy.h.tmpl +++ /dev/null @@ -1,74 +0,0 @@ -&{AMQP_ServerProxy.h} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#ifndef qpid_framing_AMQP_ServerProxy__ -#define qpid_framing_AMQP_ServerProxy__ - -#include -#include -#include - -namespace qpid { -namespace framing { - -class AMQP_ServerProxy : public AMQP_ServerOperations -{ -private: - ProtocolVersion version; - OutputHandler* out; -%{CLIST} ${sph_handler_pointer_defn} - -public: - AMQP_ServerProxy(OutputHandler* out, u_int8_t major, u_int8_t minor); - ProtocolVersion& getProtocolVersion() {return version;} - virtual ~AMQP_ServerProxy() {} - - // Get methods for handlers - -%{CLIST} ${sph_handler_pointer_get_method} - - // Inner class definitions - -%{CLIST} ${sph_inner_class_defn} - -private: - // Inner class instances - -%{CLIST} ${sph_inner_class_instance} - -public: - // Inner class instance get methods - -%{CLIST} ${sph_inner_class_get_method} - -}; /* class AMQP_ServerProxy */ - -} /* namespace framing */ -} /* namespace qpid */ - -#endif diff --git a/gentools/templ.cpp/MethodBodyClass.h.tmpl b/gentools/templ.cpp/MethodBodyClass.h.tmpl deleted file mode 100644 index 5819a9cf9c..0000000000 --- a/gentools/templ.cpp/MethodBodyClass.h.tmpl +++ /dev/null @@ -1,112 +0,0 @@ -&{${CLASS}${METHOD}Body.h} -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ - -/* - * This file is auto-generated by ${GENERATOR} - do not modify. - * Supported AMQP versions: -%{VLIST} * ${major}-${minor} - */ - -#ifndef qpid_framing_${CLASS}${METHOD}Body__ -#define qpid_framing_${CLASS}${METHOD}Body__ - -#include -#include - -#include -#include -#include -#include - -namespace qpid -{ -namespace framing -{ -${version_namespace_start} - -class ${CLASS}${METHOD}Body : public AMQMethodBody -{ - // Method field declarations - -%{FLIST} ${mb_field_declaration} - - -public: - typedef boost::shared_ptr<${CLASS}${METHOD}Body> shared_ptr; - - // Constructors and destructors - -${mb_constructor_with_initializers} - - inline ${CLASS}${METHOD}Body(u_int8_t major, u_int8_t minor): AMQMethodBody(major, minor) {} - inline ${CLASS}${METHOD}Body(ProtocolVersion& version): AMQMethodBody(version) {} - virtual ~${CLASS}${METHOD}Body() {} - - // Attribute get methods - -%{FLIST} ${mb_field_get_method} - - // Helper methods - - inline void print(std::ostream& out) const - { - out << "${CLASS}${METHOD}: "; -%{FLIST} ${mb_field_print} - } - - inline u_int16_t amqpClassId() const - { - return ${CLASS_ID_INIT}; - } - - inline u_int16_t amqpMethodId() const - { - return ${METHOD_ID_INIT}; - } - - inline u_int32_t bodySize() const - { - u_int32_t size = 0; -%{FLIST} ${mb_body_size} - return size; - } - - inline void encodeContent(Buffer&${mb_buffer_param}) const - { -%{FLIST} ${mb_encode} - } - - inline void decodeContent(Buffer&${mb_buffer_param}) - { -%{FLIST} ${mb_decode} - } - -${mb_server_operation_invoke} - -}; // class ${CLASS}${METHOD}Body - -${version_namespace_end} -} // namespace framing -} // namespace qpid - -#endif - diff --git a/gentools/templ.cpp/method/MethodBodyClass.h.tmpl b/gentools/templ.cpp/method/MethodBodyClass.h.tmpl new file mode 100644 index 0000000000..5819a9cf9c --- /dev/null +++ b/gentools/templ.cpp/method/MethodBodyClass.h.tmpl @@ -0,0 +1,112 @@ +&{${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 +#include +#include +#include + +namespace qpid +{ +namespace framing +{ +${version_namespace_start} + +class ${CLASS}${METHOD}Body : public AMQMethodBody +{ + // Method field declarations + +%{FLIST} ${mb_field_declaration} + + +public: + typedef boost::shared_ptr<${CLASS}${METHOD}Body> shared_ptr; + + // Constructors and destructors + +${mb_constructor_with_initializers} + + inline ${CLASS}${METHOD}Body(u_int8_t major, u_int8_t minor): AMQMethodBody(major, minor) {} + inline ${CLASS}${METHOD}Body(ProtocolVersion& version): AMQMethodBody(version) {} + virtual ~${CLASS}${METHOD}Body() {} + + // Attribute get methods + +%{FLIST} ${mb_field_get_method} + + // Helper methods + + inline void print(std::ostream& out) const + { + out << "${CLASS}${METHOD}: "; +%{FLIST} ${mb_field_print} + } + + inline u_int16_t amqpClassId() const + { + return ${CLASS_ID_INIT}; + } + + inline u_int16_t amqpMethodId() const + { + return ${METHOD_ID_INIT}; + } + + inline u_int32_t bodySize() const + { + u_int32_t size = 0; +%{FLIST} ${mb_body_size} + return size; + } + + inline void encodeContent(Buffer&${mb_buffer_param}) const + { +%{FLIST} ${mb_encode} + } + + inline void decodeContent(Buffer&${mb_buffer_param}) + { +%{FLIST} ${mb_decode} + } + +${mb_server_operation_invoke} + +}; // class ${CLASS}${METHOD}Body + +${version_namespace_end} +} // namespace framing +} // namespace qpid + +#endif + diff --git a/gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl b/gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl new file mode 100644 index 0000000000..a9fb0e0f69 --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_ClientOperations.h.tmpl @@ -0,0 +1,82 @@ +&{AMQP_ClientOperations.h} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#ifndef qpid_framing_AMQP_ClientOperations__ +#define qpid_framing_AMQP_ClientOperations__ + +#include + +#include +#include +#include + +namespace qpid { +namespace framing { + +class AMQP_ClientProxy; + +class AMQP_ClientOperations +{ +protected: + ProtocolVersion version; + AMQP_ClientOperations() {} + +public: + AMQP_ClientOperations(u_int8_t major, u_int8_t minor) : version(major, minor) {} + AMQP_ClientOperations(ProtocolVersion& version) : version(version) {} + virtual ~AMQP_ClientOperations() {} + + inline u_int8_t getMajor() const { return version.getMajor(); } + inline u_int8_t getMinor() const { return version.getMinor(); } + inline const ProtocolVersion& getVersion() const { return version; } + inline bool isVersion(u_int8_t _major, u_int8_t _minor) const + { + return version.equals(_major, _minor); + } + inline bool isVersion(ProtocolVersion& _version) const + { + return version.equals(_version); + } + + // Include framing constant declarations + #include + + // Inner classes + +%{CLIST} ${coh_inner_class} + + // Method handler get methods + +%{CLIST} ${coh_method_handler_get_method} + +}; /* class AMQP_ClientOperations */ + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl b/gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl new file mode 100644 index 0000000000..8cca6e5cec --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_ClientProxy.cpp.tmpl @@ -0,0 +1,52 @@ +&{AMQP_ClientProxy.cpp} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#include + +#include +#include +%{MLIST} ${cpc_method_body_include} + +namespace qpid { +namespace framing { + +AMQP_ClientProxy::AMQP_ClientProxy(OutputHandler* out, u_int8_t major, u_int8_t minor) : +%{CLIST} ${cpc_constructor_initializer} + +{} + + // Inner class instance get methods + +%{CLIST} ${cpc_inner_class_get_method} + + // Inner class implementation + +%{CLIST} ${cpc_inner_class_impl} + +} /* namespace framing */ +} /* namespace qpid */ diff --git a/gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl b/gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl new file mode 100644 index 0000000000..0653ed7186 --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_ClientProxy.h.tmpl @@ -0,0 +1,75 @@ +&{AMQP_ClientProxy.h} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#ifndef qpid_framing_AMQP_ClientProxy__ +#define qpid_framing_AMQP_ClientProxy__ + +#include +#include +#include + +namespace qpid { +namespace framing { + +class AMQP_ClientProxy : public AMQP_ClientOperations +{ +private: + + ProtocolVersion version; + OutputHandler* out; +%{CLIST} ${cph_handler_pointer_defn} + +public: + AMQP_ClientProxy(OutputHandler* out, u_int8_t major, u_int8_t minor); + ProtocolVersion& getProtocolVersion() {return version;} + virtual ~AMQP_ClientProxy() {} + + // Get methods for handlers + +%{CLIST} ${cph_handler_pointer_get_method} + + // Inner class definitions + +%{CLIST} ${cph_inner_class_defn} + +private: + // Inner class instances + +%{CLIST} ${cph_inner_class_instance} + +public: + // Inner class instance get methods + +%{CLIST} ${cph_inner_class_get_method} + +}; /* class AMQP_ClientProxy */ + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/gentools/templ.cpp/model/AMQP_Constants.h.tmpl b/gentools/templ.cpp/model/AMQP_Constants.h.tmpl new file mode 100644 index 0000000000..4631bc8de6 --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_Constants.h.tmpl @@ -0,0 +1,34 @@ +&{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/gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl b/gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl new file mode 100644 index 0000000000..9753b454ba --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_HighestVersion.h.tmpl @@ -0,0 +1,42 @@ +&{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 + + +namespace qpid { +namespace framing { + +static ProtocolVersion highestProtocolVersion(${hv_latest_major}, ${hv_latest_minor}); + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl b/gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl new file mode 100644 index 0000000000..dc2a890c88 --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_MethodVersionMap.cpp.tmpl @@ -0,0 +1,62 @@ +&{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 + +namespace qpid +{ +namespace framing +{ + +AMQP_MethodVersionMap::AMQP_MethodVersionMap() +{ +%{CLIST} ${mc_create_method_body_map_entry} +} + +AMQMethodBody* AMQP_MethodVersionMap::createMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor) +{ + iterator itr = find(createMapKey(classId, methodId, major, minor)); + if (itr == end()) + { + std::stringstream ss; + ss << "Unable to find MethodBody class for classId = " << classId << ", methodId = " << + methodId << ", AMQ protocol version = " << major << "-" << minor << "."; + throw ProtocolVersionException(ss.str()); + } + return (itr->second)(major, minor); +} + +u_int64_t AMQP_MethodVersionMap::createMapKey(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor) +{ + return ((u_int64_t)classId<<48) + ((u_int64_t)methodId<<32) + ((u_int64_t)major<<16) + minor; +} + +} /* namespace framing */ +} /* namespace qpid */ diff --git a/gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl b/gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl new file mode 100644 index 0000000000..c197871d4b --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_MethodVersionMap.h.tmpl @@ -0,0 +1,57 @@ +&{AMQP_MethodVersionMap.h} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#ifndef qpid_framing_AMQP_MethodVersionMap__ +#define qpid_framing_AMQP_MethodVersionMap__ + +#include +#include + +%{MLIST} ${mc_method_body_include} + +namespace qpid +{ +namespace framing +{ + +template AMQMethodBody* createMethodBodyFn(u_int8_t major, u_int8_t minor) { return new T(major, minor); } +typedef AMQMethodBody* (*fnPtr)(u_int8_t, u_int8_t); + +class AMQP_MethodVersionMap: public std::map +{ +protected: + u_int64_t createMapKey(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor); +public: + AMQP_MethodVersionMap(); + AMQMethodBody* createMethodBody(u_int16_t classId, u_int16_t methodId, u_int8_t major, u_int8_t minor); +}; + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl b/gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl new file mode 100644 index 0000000000..e87723667b --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_ServerOperations.h.tmpl @@ -0,0 +1,83 @@ +&{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 + +#include +#include +#include + +namespace qpid { +namespace framing { + +class AMQP_ServerProxy; +class AMQP_ClientProxy; + +class AMQP_ServerOperations +{ +protected: + ProtocolVersion version; + AMQP_ServerOperations() {} + +public: + AMQP_ServerOperations(u_int8_t major, u_int8_t minor) : version(major, minor) {} + AMQP_ServerOperations(ProtocolVersion& version) : version(version) {} + virtual ~AMQP_ServerOperations() {} + + inline u_int8_t getMajor() const { return version.getMajor(); } + inline u_int8_t getMinor() const { return version.getMinor(); } + inline const ProtocolVersion& getVersion() const { return version; } + inline bool isVersion(u_int8_t _major, u_int8_t _minor) const + { + return version.equals(_major, _minor); + } + inline bool isVersion(ProtocolVersion& _version) const + { + return version.equals(_version); + } + + // Include framing constant declarations + #include + + // Inner classes + +%{CLIST} ${soh_inner_class} + + // Method handler get methods + +%{CLIST} ${soh_method_handler_get_method} + +}; /* class AMQP_ServerOperations */ + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl b/gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl new file mode 100644 index 0000000000..cce369f98b --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_ServerProxy.cpp.tmpl @@ -0,0 +1,51 @@ +&{AMQP_ServerProxy.cpp} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#include + +#include +#include +%{MLIST} ${spc_method_body_include} + +namespace qpid { +namespace framing { + +AMQP_ServerProxy::AMQP_ServerProxy(OutputHandler* out, u_int8_t major, u_int8_t minor) : +%{CLIST} ${spc_constructor_initializer} +{} + + // Inner class instance get methods + +%{CLIST} ${spc_inner_class_get_method} + + // Inner class implementation + +%{CLIST} ${spc_inner_class_impl} + +} /* namespace framing */ +} /* namespace qpid */ diff --git a/gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl b/gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl new file mode 100644 index 0000000000..fab29f2c60 --- /dev/null +++ b/gentools/templ.cpp/model/AMQP_ServerProxy.h.tmpl @@ -0,0 +1,74 @@ +&{AMQP_ServerProxy.h} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +#ifndef qpid_framing_AMQP_ServerProxy__ +#define qpid_framing_AMQP_ServerProxy__ + +#include +#include +#include + +namespace qpid { +namespace framing { + +class AMQP_ServerProxy : public AMQP_ServerOperations +{ +private: + ProtocolVersion version; + OutputHandler* out; +%{CLIST} ${sph_handler_pointer_defn} + +public: + AMQP_ServerProxy(OutputHandler* out, u_int8_t major, u_int8_t minor); + ProtocolVersion& getProtocolVersion() {return version;} + virtual ~AMQP_ServerProxy() {} + + // Get methods for handlers + +%{CLIST} ${sph_handler_pointer_get_method} + + // Inner class definitions + +%{CLIST} ${sph_inner_class_defn} + +private: + // Inner class instances + +%{CLIST} ${sph_inner_class_instance} + +public: + // Inner class instance get methods + +%{CLIST} ${sph_inner_class_get_method} + +}; /* class AMQP_ServerProxy */ + +} /* namespace framing */ +} /* namespace qpid */ + +#endif diff --git a/gentools/templ.java/AmqpConstantsClass.tmpl b/gentools/templ.java/AmqpConstantsClass.tmpl deleted file mode 100644 index 8d459f2977..0000000000 --- a/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/gentools/templ.java/MethodBodyClass.tmpl b/gentools/templ.java/MethodBodyClass.tmpl deleted file mode 100644 index eb730fd891..0000000000 --- a/gentools/templ.java/MethodBodyClass.tmpl +++ /dev/null @@ -1,183 +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} - - protected 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 AMQFrame createAMQFrame(int channelId, byte major, byte minor -%{FLIST} ${mb_field_parameter_list} - ) - { - return createAMQFrame(channelId, major, minor, getClazz(major,minor), getMethod(major,minor) -%{FLIST} ${mb_field_passed_parameter_list} - ); - - - - } - - public static AMQFrame createAMQFrame(int channelId, byte major, byte minor, int clazzID, int methodID -%{FLIST} ${mb_field_parameter_list} - ) - { - ${CLASS}${METHOD}Body body = new ${CLASS}${METHOD}Body(major, minor, clazzID, methodID -%{FLIST} ${mb_field_passed_parameter_list} - ); - - - AMQFrame frame = new AMQFrame(channelId, body); - return frame; - } - -} diff --git a/gentools/templ.java/MethodRegistryClass.tmpl b/gentools/templ.java/MethodRegistryClass.tmpl deleted file mode 100644 index 8752be4dc8..0000000000 --- a/gentools/templ.java/MethodRegistryClass.tmpl +++ /dev/null @@ -1,153 +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 java.util.HashMap; -import org.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; - -public class MainRegistry -{ - private static final HashMap classIDMethodIDVersionBodyMap = new HashMap(); - - - 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} - - configure(); - } - - 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); - - } - - - private static void configure() - { - for(int i = 0 ; i < _specificRegistries.length; i++) - { - VersionSpecificRegistry[] registries = _specificRegistries[i]; - if(registries != null) - { - for(int j = 0 ; j < registries.length; j++) - { - VersionSpecificRegistry registry = registries[j]; - - if(registry != null) - { - registry.configure(); - } - } - } - } - - } - -} diff --git a/gentools/templ.java/ProtocolVersionListClass.tmpl b/gentools/templ.java/ProtocolVersionListClass.tmpl deleted file mode 100644 index bc98e0c1ea..0000000000 --- a/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/gentools/templ.java/model/ProtocolVersionListClass.vm b/gentools/templ.java/model/ProtocolVersionListClass.vm new file mode 100644 index 0000000000..18d90fab29 --- /dev/null +++ b/gentools/templ.java/model/ProtocolVersionListClass.vm @@ -0,0 +1,148 @@ +#set( $filename = "ProtocolVersion.java" ) +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +/* +* This file is auto-generated by $generator - do not modify. +* Supported AMQP versions: +#foreach( $version in $model.getVersionSet() ) +* $version.getMajor()-$version.getMinor() +#end +*/ + +package org.apache.qpid.framing; + +import java.util.SortedSet; +import java.util.Collections; +import java.util.TreeSet; + + +public class ProtocolVersion implements Comparable +{ + private final byte _majorVersion; + private final byte _minorVersion; + + + public ProtocolVersion(byte majorVersion, byte minorVersion) + { + _majorVersion = majorVersion; + _minorVersion = minorVersion; + } + + public byte getMajorVersion() + { + return _majorVersion; + } + + public byte getMinorVersion() + { + return _minorVersion; + } + + + public int compareTo(Object o) + { + ProtocolVersion pv = (ProtocolVersion) o; + + /* + * 0-8 has it's major and minor numbers the wrong way round (it's actually 8-0)... + * so we need to deal with that case specially + */ + + if((_majorVersion == (byte) 8) && (_minorVersion == (byte) 0)) + { + ProtocolVersion fixedThis = new ProtocolVersion(_minorVersion, _majorVersion); + return fixedThis.compareTo(pv); + } + + if((pv.getMajorVersion() == (byte) 8) && (pv.getMinorVersion() == (byte) 0)) + { + ProtocolVersion fixedOther = new ProtocolVersion(pv.getMinorVersion(), pv.getMajorVersion()); + return this.compareTo(fixedOther); + } + + if(_majorVersion > pv.getMajorVersion()) + { + return 1; + } + else if(_majorVersion < pv.getMajorVersion()) + { + return -1; + } + else if(_minorVersion > pv.getMinorVersion()) + { + return 1; + } + else if(getMinorVersion() < pv.getMinorVersion()) + { + return -1; + } + else + { + return 0; + } + + } + + public boolean equals(Object o) + { + return o != null && (o == this || (compareTo(o) == 0)); + } + + public int hashCode() + { + return (0xFF & (int)_minorVersion) | ((0xFF & (int)_majorVersion) << 8); + } + + + public boolean isSupported() + { + return _supportedVersions.contains(this); + } + + public static ProtocolVersion getLatestSupportedVersion() + { + return _supportedVersions.last(); + } + + private static final SortedSet _supportedVersions; + + static + { + SortedSet versions = new TreeSet(); + +#foreach( $version in $model.getVersionSet() ) + versions.add(new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor())); +#end + _supportedVersions = Collections.unmodifiableSortedSet(versions); + } + + + public static SortedSet getSupportedProtocolVersions() + { + return _supportedVersions; + } + + + + + +} diff --git a/gentools/templ.java/model/version/AmqpConstantsClass.vm b/gentools/templ.java/model/version/AmqpConstantsClass.vm new file mode 100644 index 0000000000..8d459f2977 --- /dev/null +++ b/gentools/templ.java/model/version/AmqpConstantsClass.vm @@ -0,0 +1,37 @@ +&{AmqpConstants.java} +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by ${GENERATOR} - do not modify. + * Supported AMQP versions: +%{VLIST} * ${major}-${minor} + */ + +package org.apache.qpid.framing; + +class AmqpConstants +{ + // Constant getValue methods + +%{TLIST} ${const_get_method} + +} diff --git a/gentools/templ.java/model/version/MethodRegistryClass.vm b/gentools/templ.java/model/version/MethodRegistryClass.vm new file mode 100644 index 0000000000..2501446d19 --- /dev/null +++ b/gentools/templ.java/model/version/MethodRegistryClass.vm @@ -0,0 +1,136 @@ +#set( $filename = "amqp_$version.getMajor()_$version.getMinor()/MethodRegistry_${version.getMajor()}_${version.getMinor()}.java") +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +/* + * This file is auto-generated by $generator - do not modify. + * Supported AMQP version: + * $version.getMajor()-$version.getMinor() + */ + +package org.apache.qpid.framing.amqp_${version.getMajor()}_${version.getMinor()}; + +import org.apache.qpid.framing.AMQMethodBodyInstanceFactory; +import org.apache.qpid.framing.AMQFrameDecodingException; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.MethodRegistry; +import org.apache.qpid.framing.ProtocolVersion; + + +import org.apache.log4j.Logger; +import org.apache.mina.common.ByteBuffer; + +public class MethodRegistry_$version.getMajor()_$version.getMinor() extends MethodRegistry +{ + + private static final Logger _log = Logger.getLogger(MethodRegistry.class); + +#set( $specificModel = $model.asSingleVersionModel() ) + + + + private final AMQMethodBodyInstanceFactory[][] _factories = new AMQMethodBodyInstanceFactory[$specificModel.getMaximumClassId()+1][]; + + public MethodRegistry_$version.getMajor()_$version.getMinor()() + { + this(new ProtocolVersion((byte)$version.getMajor(),(byte)$version.getMinor())); + } + + public MethodRegistry_$version.getMajor()_$version.getMinor()(ProtocolVersion pv) + { + super(pv); +#foreach( $amqpClass in $specificModel.getClassList() ) +#set( $amqpClassNameFirstChar = $amqpClass.getName().substring(0,1) ) +#set( $amqpClassNameFirstCharU = $amqpClassNameFirstChar.toUpperCase() ) +#set( $amqpClassNameUpperCamel = "$amqpClassNameFirstCharU$amqpClass.getName().substring(1)" ) + + + + // Register method body instance factories for the $amqpClassNameUpperCamel class. + + _factories[$amqpClass.getClassId()] = new AMQMethodBodyInstanceFactory[$amqpClass.getMaximumMethodId()+1]; + +#foreach( $amqpMethod in $amqpClass.getMethodList() ) +#set( $amqpMethodNameFirstChar = $amqpMethod.getName().substring(0,1) ) +#set( $amqpMethodNameFirstCharU = $amqpMethodNameFirstChar.toUpperCase() ) +#set( $amqpMethodNameUpperCamel = "$amqpMethodNameFirstCharU$amqpMethod.getName().substring(1)" ) + _factories[$amqpClass.getClassId()][$amqpMethod.getMethodId()] = ${amqpClassNameUpperCamel}${amqpMethodNameUpperCamel}BodyImpl.getFactory(); +#end + +#end + + + } + + + public AMQMethodBody convertToBody(ByteBuffer in, long size) + throws AMQFrameDecodingException + { + int classId = in.getUnsignedShort(); + int methodId = in.getUnsignedShort(); + + AMQMethodBodyInstanceFactory bodyFactory; + try + { + bodyFactory = _factories[classId][methodId]; + } + catch(NullPointerException e) + { + throw new AMQFrameDecodingException(_log, + "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + } + catch(IndexOutOfBoundsException e) + { + if(classId >= _factories.length) + { + throw new AMQFrameDecodingException(_log, + "Class " + classId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + + } + else + { + throw new AMQFrameDecodingException(_log, + "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + + } + } + + + if (bodyFactory == null) + { + throw new AMQFrameDecodingException(_log, + "Method " + methodId + " unknown in AMQP version $version.getMajor()-$version.getMinor()" + + " (while trying to decode class " + classId + " method " + methodId + "."); + } + + + return bodyFactory.newInstance(in, size); + + + } + + + + +} diff --git a/java/broker/bin/qpid-server-bdb.bat b/java/broker/bin/qpid-server-bdb.bat index 5c8b74e163..833415cb05 100644 --- a/java/broker/bin/qpid-server-bdb.bat +++ b/java/broker/bin/qpid-server-bdb.bat @@ -1,3 +1,3 @@ -set BDBSTORE_HOME=c:\qpid\trunk\java\bdbstore +set BDBSTORE_HOME=c:\qpid-bdb\bdbstore set QPID_MODULE_JARS=%BDBSTORE_HOME%\target\qpid-bdbstore-1.0-incubating-M2-SNAPSHOT.jar;%BDBSTORE_HOME%\lib\bdb\je-3.1.0.jar .\qpid-server.bat \ No newline at end of file diff --git a/java/broker/distribution/src/main/assembly/broker-bin-tests.xml b/java/broker/distribution/src/main/assembly/broker-bin-tests.xml index fa017d6232..a14360bd73 100644 --- a/java/broker/distribution/src/main/assembly/broker-bin-tests.xml +++ b/java/broker/distribution/src/main/assembly/broker-bin-tests.xml @@ -92,7 +92,7 @@ ../../common/bin/qpid-run qpid-${qpid.version}/bin qpid-run - 493 + 473 diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml index 0b4091efa5..a3a33e11c5 100644 --- a/java/broker/etc/config.xml +++ b/java/broker/etc/config.xml @@ -89,8 +89,8 @@ localhost - - org.apache.qpid.server.store.MemoryMessageStore + org.apache.qpid.server.store.berkeleydb.BDBMessageStore + localhost-store @@ -101,7 +101,9 @@ org.apache.qpid.server.store.MemoryMessageStore - + + development-store + @@ -110,7 +112,10 @@ org.apache.qpid.server.store.MemoryMessageStore - + + test-store + + diff --git a/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml index 0cf2579137..81824fde93 100644 --- a/java/broker/etc/log4j.xml +++ b/java/broker/etc/log4j.xml @@ -36,20 +36,22 @@ - - + + + + --> - + diff --git a/java/broker/etc/virtualhosts.xml b/java/broker/etc/virtualhosts.xml index 52ff23e090..f73399a74c 100644 --- a/java/broker/etc/virtualhosts.xml +++ b/java/broker/etc/virtualhosts.xml @@ -27,8 +27,13 @@ direct + test.direct - true + + + true + + topic @@ -40,7 +45,7 @@ 4235264 2117632 600000 - + true queue diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index 7ceb3a7eef..be2cee79ee 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -433,7 +433,10 @@ public class AMQChannel } - /** Called to resend all outstanding unacknowledged messages to this same channel. */ + /** Called to resend all outstanding unacknowledged messages to this same channel. + * @param session the session + * @param requeue if true then requeue, else resend + * @throws org.apache.qpid.AMQException */ public void resend(final AMQProtocolSession session, final boolean requeue) throws AMQException { final List msgToRequeue = new LinkedList(); @@ -752,7 +755,9 @@ public class AMQChannel for (RequiredDeliveryException bouncedMessage : _returnMessages) { AMQMessage message = bouncedMessage.getAMQMessage(); - message.writeReturn(session, _channelId, bouncedMessage.getReplyCode().getCode(), new AMQShortString(bouncedMessage.getMessage())); + session.getProtocolOutputConverter().writeReturn(message, _channelId, + bouncedMessage.getReplyCode().getCode(), + new AMQShortString(bouncedMessage.getMessage())); } _returnMessages.clear(); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java index 42fe8c5274..a48bc5df7f 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -45,7 +45,7 @@ import org.apache.mina.common.SimpleByteBufferAllocator; import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; import org.apache.mina.transport.socket.nio.SocketSessionConfig; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.ProtocolVersionList; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.server.configuration.VirtualHostConfiguration; import org.apache.qpid.server.protocol.AMQPFastProtocolHandler; @@ -59,7 +59,8 @@ import org.apache.qpid.url.URLSyntaxException; * Main entry point for AMQPD. * */ -public class Main implements ProtocolVersionList +@SuppressWarnings({"AccessStaticViaInstance"}) +public class Main { private static final Logger _logger = Logger.getLogger(Main.class); @@ -143,12 +144,21 @@ public class Main implements ProtocolVersionList else if (commandLine.hasOption("v")) { String ver = "Qpid 0.9.0.0"; - String protocol = "AMQP version(s) [major.minor]: "; - for (int i=0; i 0) - protocol += ", "; - protocol += pv[i][PROTOCOL_MAJOR] + "." + pv[i][PROTOCOL_MINOR]; + if(first) + { + first = false; + } + else + { + protocol.append(", "); + } + protocol.append(pv.getMajorVersion()).append('-').append(pv.getMinorVersion()); + } System.out.println(ver + " (" + protocol + ")"); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java b/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java index fdf087fdea..99cc60011a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/ack/UnacknowledgedMessageMapImpl.java @@ -209,7 +209,7 @@ public class UnacknowledgedMessageMapImpl implements UnacknowledgedMessageMap if(consumerTag != null) { - msg.writeDeliver(protocolSession, channelId, deliveryTag, consumerTag); + protocolSession.getProtocolOutputConverter().writeDeliver(msg, channelId, deliveryTag, consumerTag); } } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java b/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java index 348bfa5e68..bdabcbf5be 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java +++ b/java/broker/src/main/java/org/apache/qpid/server/filter/PropertyExpression.java @@ -25,7 +25,8 @@ import java.util.HashMap; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.BasicContentHeaderProperties; +import org.apache.qpid.framing.CommonContentHeaderProperties; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.server.queue.AMQMessage; /** @@ -63,8 +64,9 @@ public class PropertyExpression implements Expression { try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; - return _properties.getReplyTo(); + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; + AMQShortString replyTo = _properties.getReplyTo(); + return replyTo == null ? null : replyTo.toString(); } catch (AMQException e) { @@ -83,8 +85,9 @@ public class PropertyExpression implements Expression { try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; - return _properties.getType(); + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; + AMQShortString type = _properties.getType(); + return type == null ? null : type.toString(); } catch (AMQException e) { @@ -126,7 +129,7 @@ public class PropertyExpression implements Expression { try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; return (int) _properties.getPriority(); } catch (AMQException e) @@ -147,8 +150,9 @@ public class PropertyExpression implements Expression try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; - return _properties.getMessageId(); + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; + AMQShortString messageId = _properties.getMessageId(); + return messageId == null ? null : messageId; } catch (AMQException e) { @@ -168,7 +172,7 @@ public class PropertyExpression implements Expression try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; return _properties.getTimestamp(); } catch (AMQException e) @@ -189,8 +193,9 @@ public class PropertyExpression implements Expression try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; - return _properties.getCorrelationId(); + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; + AMQShortString correlationId = _properties.getCorrelationId(); + return correlationId == null ? null : correlationId.toString(); } catch (AMQException e) { @@ -210,7 +215,7 @@ public class PropertyExpression implements Expression try { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; return _properties.getExpiration(); } catch (AMQException e) @@ -254,7 +259,7 @@ public class PropertyExpression implements Expression else { - BasicContentHeaderProperties _properties = (BasicContentHeaderProperties) message.getContentHeaderBody().properties; + CommonContentHeaderProperties _properties = (CommonContentHeaderProperties) message.getContentHeaderBody().properties; if(_logger.isDebugEnabled()) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java index f93b2b25e6..269b68ff6b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicAckMethodHandler.java @@ -61,6 +61,6 @@ public class BasicAckMethodHandler implements StateAwareMethodListener throw evt.getMethod().getChannelNotFoundException(evt.getChannelId()); } - channel.setPrefetchCount(evt.getMethod().prefetchCount); - channel.setPrefetchSize(evt.getMethod().prefetchSize); + channel.setPrefetchCount(evt.getMethod().getPrefetchCount()); + channel.setPrefetchSize(evt.getMethod().getPrefetchSize()); // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java index bc11e4652c..601187d2cd 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicRecoverMethodHandler.java @@ -54,7 +54,7 @@ public class BasicRecoverMethodHandler implements StateAwareMethodListener getInstance() { @@ -62,23 +63,23 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< { AMQProtocolSession session = stateManager.getProtocolSession(); final ConnectionStartOkBody body = evt.getMethod(); - _logger.info("SASL Mechanism selected: " + body.mechanism); - _logger.info("Locale selected: " + body.locale); + _logger.info("SASL Mechanism selected: " + body.getMechanism()); + _logger.info("Locale selected: " + body.getLocale()); AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager(); SaslServer ss = null; try { - ss = authMgr.createSaslServer(String.valueOf(body.mechanism), session.getLocalFQDN()); + ss = authMgr.createSaslServer(String.valueOf(body.getMechanism()), session.getLocalFQDN()); session.setSaslServer(ss); - AuthenticationResult authResult = authMgr.authenticate(ss, body.response); + AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse()); //save clientProperties if (session.getClientProperties() == null) { - session.setClientProperties(body.clientProperties); + session.setClientProperties(body.getClientProperties()); } switch (authResult.status) @@ -141,6 +142,15 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener< _logger.info("Framesize set to " + framesize); return framesize; } + + + static int getConfiguredMaxChannels() + { + final Configuration config = ApplicationRegistry.getInstance().getConfiguration(); + final int maxChannels = config.getInt("advanced.maxchannels", DEFAULT_CHANNEL_MAX); + _logger.info("Max Channels set to " + maxChannels); + return maxChannels; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java index ab7695955c..8a6b518934 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionTuneOkMethodHandler.java @@ -49,6 +49,6 @@ public class ConnectionTuneOkMethodHandler implements StateAwareMethodListener QueueRegistry queueRegistry = virtualHost.getQueueRegistry(); final QueueBindBody body = evt.getMethod(); + + AMQShortString routingKey = body.getRoutingKey(); final AMQQueue queue; - if (body.queue == null) + if (body.getQueue() == null) { AMQChannel channel = session.getChannel(evt.getChannelId()); @@ -77,33 +80,35 @@ public class QueueBindHandler implements StateAwareMethodListener { throw body.getChannelException(AMQConstant.NOT_FOUND, "No default queue defined on channel and queue was null"); } - - if (body.routingKey == null) + + + + if (routingKey == null) { - body.routingKey = queue.getName(); + routingKey = queue.getName(); } } else { - queue = queueRegistry.getQueue(body.queue); + queue = queueRegistry.getQueue(body.getQueue()); } if (queue == null) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.queue + " does not exist."); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Queue " + body.getQueue() + " does not exist."); } - final Exchange exch = exchangeRegistry.getExchange(body.exchange); + final Exchange exch = exchangeRegistry.getExchange(body.getExchange()); if (exch == null) { - throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.exchange + " does not exist."); + throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.getExchange() + " does not exist."); } try { - queue.bind(body.routingKey, body.arguments, exch); + queue.bind(routingKey, body.getArguments(), exch); } catch (AMQInvalidRoutingKeyException rke) { - throw body.getChannelException(AMQConstant.INVALID_ROUTING_KEY, body.routingKey.toString()); + throw body.getChannelException(AMQConstant.INVALID_ROUTING_KEY, routingKey.toString()); } catch (AMQException e) { @@ -112,9 +117,9 @@ public class QueueBindHandler implements StateAwareMethodListener if (_log.isInfoEnabled()) { - _log.info("Binding queue " + queue + " to exchange " + exch + " with routing key " + body.routingKey); + _log.info("Binding queue " + queue + " to exchange " + exch + " with routing key " + routingKey); } - if (!body.nowait) + if (!body.getNowait()) { // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java index 8b2467f47d..5a49368c1c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java @@ -78,10 +78,12 @@ public class QueueDeclareHandler implements StateAwareMethodListener channel.setLocalTransactional(); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - session.writeFrame(TxSelectOkBody.createAMQFrame(evt.getChannelId(), (byte) 8, (byte) 0)); + TxSelectBody txSelect = createTxSelectBody(); + session.writeFrame(new AMQFrame(evt.getChannelId(), txSelect)); + } + + private TxSelectBody createTxSelectBody() + { + return new TxSelectBodyImpl(); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java new file mode 100644 index 0000000000..e01c5aabbf --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverter.java @@ -0,0 +1,57 @@ +/* + * + * 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 Qpid Gentools v.0.1 - do not modify. + * Supported AMQP versions: + * 8-0 + */ +package org.apache.qpid.server.output; + +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.AMQException; + +public interface ProtocolOutputConverter +{ + void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag); + + interface Factory + { + ProtocolOutputConverter newInstance(AMQProtocolSession session); + } + + void writeDeliver(AMQMessage message, int channelId, long deliveryTag, AMQShortString consumerTag) + throws AMQException; + + void writeGetOk(AMQMessage message, int channelId, long deliveryTag, int queueSize) throws AMQException; + + byte getProtocolMinorVersion(); + + byte getProtocolMajorVersion(); + + void writeReturn(AMQMessage message, int channelId, int replyCode, AMQShortString replyText) + throws AMQException; + + void writeFrame(AMQDataBlock block); +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java new file mode 100644 index 0000000000..8366c426dd --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/output/ProtocolOutputConverterRegistry.java @@ -0,0 +1,62 @@ +/* + * + * 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 Qpid Gentools v.0.1 - do not modify. + * Supported AMQP versions: + * 8-0 + */ +package org.apache.qpid.server.output; + +import org.apache.qpid.server.output.ProtocolOutputConverter.Factory; +import org.apache.qpid.server.output.amqp0_8.ProtocolOutputConverterImpl; +import org.apache.qpid.server.protocol.AMQProtocolSession; + +import java.util.Map; +import java.util.HashMap; + +public class ProtocolOutputConverterRegistry +{ + + private static final Map> _registry = + new HashMap>(); + + + static + { + register((byte) 8, (byte) 0, ProtocolOutputConverterImpl.getInstanceFactory()); + } + + private static void register(byte major, byte minor, Factory converter) + { + if(!_registry.containsKey(major)) + { + _registry.put(major, new HashMap()); + } + _registry.get(major).put(minor, converter); + } + + + public static ProtocolOutputConverter getConverter(AMQProtocolSession session) + { + return _registry.get(session.getProtocolMajorVersion()).get(session.getProtocolMinorVersion()).newInstance(session); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java b/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java new file mode 100644 index 0000000000..bd5bb632fe --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/output/amqp0_8/ProtocolOutputConverterImpl.java @@ -0,0 +1,288 @@ +/* + * + * 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 Qpid Gentools v.0.1 - do not modify. + * Supported AMQP versions: + * 8-0 + */ +package org.apache.qpid.server.output.amqp0_8; + +import org.apache.qpid.server.protocol.AMQProtocolSession; +import org.apache.qpid.server.queue.AMQMessage; +import org.apache.qpid.server.queue.AMQMessageHandle; +import org.apache.qpid.server.store.StoreContext; +import org.apache.qpid.server.output.ProtocolOutputConverter; +import org.apache.qpid.framing.*; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.AMQException; + +import org.apache.mina.common.ByteBuffer; + +import java.util.Iterator; + +public class ProtocolOutputConverterImpl implements ProtocolOutputConverter +{ + + public static Factory getInstanceFactory() + { + return new Factory() + { + + public ProtocolOutputConverter newInstance(AMQProtocolSession session) + { + return new ProtocolOutputConverterImpl(session); + } + }; + } + + private final AMQProtocolSession _protocolSession; + + private ProtocolOutputConverterImpl(AMQProtocolSession session) + { + _protocolSession = session; + } + + + public AMQProtocolSession getProtocolSession() + { + return _protocolSession; + } + + public void writeDeliver(AMQMessage message, int channelId, long deliveryTag, AMQShortString consumerTag) + throws AMQException + { + ByteBuffer deliver = createEncodedDeliverFrame(message, channelId, deliveryTag, consumerTag); + AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId, + message.getContentHeaderBody()); + + final AMQMessageHandle messageHandle = message.getMessageHandle(); + final StoreContext storeContext = message.getStoreContext(); + final long messageId = message.getMessageId(); + + final int bodyCount = messageHandle.getBodyCount(storeContext,messageId); + + if(bodyCount == 0) + { + SmallCompositeAMQDataBlock compositeBlock = new SmallCompositeAMQDataBlock(deliver, + contentHeader); + + writeFrame(compositeBlock); + } + else + { + + + // + // Optimise the case where we have a single content body. In that case we create a composite block + // so that we can writeDeliver out the deliver, header and body with a single network writeDeliver. + // + ContentChunk cb = messageHandle.getContentChunk(storeContext,messageId, 0); + + AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb)); + AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody}; + CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(deliver, headerAndFirstContent); + writeFrame(compositeBlock); + + // + // Now start writing out the other content bodies + // + for(int i = 1; i < bodyCount; i++) + { + cb = messageHandle.getContentChunk(storeContext,messageId, i); + writeFrame(new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb))); + } + + + } + + + } + + + public void writeGetOk(AMQMessage message, int channelId, long deliveryTag, int queueSize) throws AMQException + { + + final AMQMessageHandle messageHandle = message.getMessageHandle(); + final StoreContext storeContext = message.getStoreContext(); + final long messageId = message.getMessageId(); + + ByteBuffer deliver = createEncodedGetOkFrame(message, channelId, deliveryTag, queueSize); + + + AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId, + message.getContentHeaderBody()); + + final int bodyCount = messageHandle.getBodyCount(storeContext,messageId); + if(bodyCount == 0) + { + SmallCompositeAMQDataBlock compositeBlock = new SmallCompositeAMQDataBlock(deliver, + contentHeader); + writeFrame(compositeBlock); + } + else + { + + + // + // Optimise the case where we have a single content body. In that case we create a composite block + // so that we can writeDeliver out the deliver, header and body with a single network writeDeliver. + // + ContentChunk cb = messageHandle.getContentChunk(storeContext,messageId, 0); + + AMQDataBlock firstContentBody = new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb)); + AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody}; + CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(deliver, headerAndFirstContent); + writeFrame(compositeBlock); + + // + // Now start writing out the other content bodies + // + for(int i = 1; i < bodyCount; i++) + { + cb = messageHandle.getContentChunk(storeContext, messageId, i); + writeFrame(new AMQFrame(channelId, getProtocolSession().getRegistry().getProtocolVersionMethodConverter().convertToBody(cb))); + } + + + } + + + } + + + private ByteBuffer createEncodedDeliverFrame(AMQMessage message, int channelId, long deliveryTag, AMQShortString consumerTag) + throws AMQException + { + final MessagePublishInfo pb = message.getMessagePublishInfo(); + final AMQMessageHandle messageHandle = message.getMessageHandle(); + + AMQFrame deliverFrame = BasicDeliverBody.createAMQFrame(channelId, getProtocolMajorVersion(), + getProtocolMinorVersion(), + consumerTag, + deliveryTag, pb.getExchange(), messageHandle.isRedelivered(), + pb.getRoutingKey()); + + ByteBuffer buf = ByteBuffer.allocate((int) deliverFrame.getSize()); // XXX: Could cast be a problem? + deliverFrame.writePayload(buf); + buf.flip(); + return buf; + } + + private ByteBuffer createEncodedGetOkFrame(AMQMessage message, int channelId, long deliveryTag, int queueSize) + throws AMQException + { + final MessagePublishInfo pb = message.getMessagePublishInfo(); + final AMQMessageHandle messageHandle = message.getMessageHandle(); + + AMQFrame getOkFrame = BasicGetOkBody.createAMQFrame(channelId, + getProtocolMajorVersion(), + getProtocolMinorVersion(), + deliveryTag, pb.getExchange(), + queueSize, + messageHandle.isRedelivered(), + pb.getRoutingKey()); + ByteBuffer buf = ByteBuffer.allocate((int) getOkFrame.getSize()); // XXX: Could cast be a problem? + getOkFrame.writePayload(buf); + buf.flip(); + return buf; + } + + public byte getProtocolMinorVersion() + { + return getProtocolSession().getProtocolMinorVersion(); + } + + public byte getProtocolMajorVersion() + { + return getProtocolSession().getProtocolMajorVersion(); + } + + private ByteBuffer createEncodedReturnFrame(AMQMessage message, int channelId, int replyCode, AMQShortString replyText) throws AMQException + { + AMQFrame returnFrame = BasicReturnBody.createAMQFrame(channelId, + getProtocolMajorVersion(), + getProtocolMinorVersion(), + message.getMessagePublishInfo().getExchange(), + replyCode, replyText, + message.getMessagePublishInfo().getRoutingKey()); + ByteBuffer buf = ByteBuffer.allocate((int) returnFrame.getSize()); // XXX: Could cast be a problem? + returnFrame.writePayload(buf); + buf.flip(); + return buf; + } + + public void writeReturn(AMQMessage message, int channelId, int replyCode, AMQShortString replyText) + throws AMQException + { + ByteBuffer returnFrame = createEncodedReturnFrame(message, channelId, replyCode, replyText); + + AMQDataBlock contentHeader = ContentHeaderBody.createAMQFrame(channelId, + message.getContentHeaderBody()); + + Iterator bodyFrameIterator = message.getBodyFrameIterator(getProtocolSession(), channelId); + // + // Optimise the case where we have a single content body. In that case we create a composite block + // so that we can writeDeliver out the deliver, header and body with a single network writeDeliver. + // + if (bodyFrameIterator.hasNext()) + { + AMQDataBlock firstContentBody = bodyFrameIterator.next(); + AMQDataBlock[] headerAndFirstContent = new AMQDataBlock[]{contentHeader, firstContentBody}; + CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(returnFrame, headerAndFirstContent); + writeFrame(compositeBlock); + } + else + { + CompositeAMQDataBlock compositeBlock = new CompositeAMQDataBlock(returnFrame, + new AMQDataBlock[]{contentHeader}); + + writeFrame(compositeBlock); + } + + // + // Now start writing out the other content bodies + // TODO: MINA needs to be fixed so the the pending writes buffer is not unbounded + // + while (bodyFrameIterator.hasNext()) + { + writeFrame(bodyFrameIterator.next()); + } + } + + + public void writeFrame(AMQDataBlock block) + { + getProtocolSession().writeFrame(block); + } + + + public void confirmConsumerAutoClose(int channelId, AMQShortString consumerTag) + { + + writeFrame(BasicCancelOkBody.createAMQFrame(channelId, + getProtocolMajorVersion(), + getProtocolMinorVersion(), + consumerTag // consumerTag + )); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java index 2de32c2f0f..587cb3b2aa 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java @@ -43,25 +43,15 @@ import org.apache.qpid.AMQException; import org.apache.qpid.codec.AMQCodecFactory; import org.apache.qpid.codec.AMQDecoder; import org.apache.qpid.common.ClientProperties; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionStartBody; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.HeartbeatBody; -import org.apache.qpid.framing.MainRegistry; -import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersionList; -import org.apache.qpid.framing.VersionSpecificRegistry; -import org.apache.qpid.framing.ChannelCloseOkBody; +import org.apache.qpid.framing.*; +import org.apache.qpid.framing.amqp_8_0.ConnectionStartBodyImpl; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.output.ProtocolOutputConverter; +import org.apache.qpid.server.output.ProtocolOutputConverterRegistry; import org.apache.qpid.server.management.Managable; import org.apache.qpid.server.management.ManagedObject; import org.apache.qpid.server.registry.ApplicationRegistry; @@ -71,7 +61,6 @@ import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; public class AMQMinaProtocolSession implements AMQProtocolSession, - ProtocolVersionList, Managable { private static final Logger _logger = Logger.getLogger(AMQProtocolSession.class); @@ -111,12 +100,13 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, private long _maxNoOfChannels = 1000; /* AMQP Version for this session */ - private byte _major = pv[pv.length - 1][PROTOCOL_MAJOR]; - private byte _minor = pv[pv.length - 1][PROTOCOL_MINOR]; + private ProtocolVersion _protocolVersion = ProtocolVersion.getLatestSupportedVersion(); + private FieldTable _clientProperties; private final List _taskList = new CopyOnWriteArrayList(); - private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(pv[pv.length - 1][PROTOCOL_MAJOR], pv[pv.length - 1][PROTOCOL_MINOR]); + private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion); private List _closingChannelsList = new ArrayList(); + private ProtocolOutputConverter _protocolOutputConverter; public ManagedObject getManagedObject() @@ -195,86 +185,123 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, _lastReceived = message; if (message instanceof ProtocolInitiation) { - ProtocolInitiation pi = (ProtocolInitiation) message; - // this ensures the codec never checks for a PI message again - ((AMQDecoder) _codecFactory.getDecoder()).setExpectProtocolInitiation(false); - try - { - pi.checkVersion(this); // Fails if not correct + protocolInitiationReceived((ProtocolInitiation) message); - // This sets the protocol version (and hence framing classes) for this session. - setProtocolVersion(pi.protocolMajor, pi.protocolMinor); + } + else if (message instanceof AMQFrame) + { + AMQFrame frame = (AMQFrame) message; + frameReceived(frame); - String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager().getMechanisms(); + } + else + { + throw new UnknnownMessageTypeException(message); + } + } - String locales = "en_US"; + private void frameReceived(AMQFrame frame) + throws AMQException + { + int channelId = frame.getChannel(); + AMQBody body = frame.getBodyFrame(); - // Interfacing with generated code - be aware of possible changes to parameter order as versions change. - AMQFrame response = ConnectionStartBody.createAMQFrame((short) 0, - _major, _minor, // AMQP version (major, minor) - locales.getBytes(), // locales - mechanisms.getBytes(), // mechanisms - null, // serverProperties - (short) _major, // versionMajor - (short) _minor); // versionMinor - _minaProtocolSession.write(response); - } - catch (AMQException e) - { - _logger.error("Received incorrect protocol initiation", e); - /* Find last protocol version in protocol version list. Make sure last protocol version - listed in the build file (build-module.xml) is the latest version which will be used - here. */ - int i = pv.length - 1; - _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); - // TODO: Close connection (but how to wait until message is sent?) - // ritchiem 2006-12-04 will this not do? -// WriteFuture future = _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); -// future.join(); -// close connection + if(_logger.isDebugEnabled()) + { + _logger.debug("Frame Received: " + frame); + } - } + if (body instanceof AMQMethodBodyImpl) + { + methodFrameReceived(channelId, (AMQMethodBodyImpl)body); + } + else if (body instanceof ContentHeaderBody) + { + contentHeaderReceived(channelId, (ContentHeaderBody)body); + } + else if (body instanceof ContentBody) + { + contentBodyReceived(channelId, (ContentBody)body); + } + else if (body instanceof HeartbeatBody) + { + // NO OP } else { - AMQFrame frame = (AMQFrame) message; - - if (frame.getBodyFrame() instanceof AMQMethodBody) - { - methodFrameReceived(frame); - } - else - { - contentFrameReceived(frame); - } + _logger.warn("Unrecognised frame " + frame.getClass().getName()); } } - private void methodFrameReceived(AMQFrame frame) + private void protocolInitiationReceived(ProtocolInitiation pi) { - if (_logger.isDebugEnabled()) + // this ensures the codec never checks for a PI message again + ((AMQDecoder) _codecFactory.getDecoder()).setExpectProtocolInitiation(false); + try + { + pi.checkVersion(); // Fails if not correct + + // This sets the protocol version (and hence framing classes) for this session. + setProtocolVersion(pi._protocolMajor, pi._protocolMinor); + + String mechanisms = ApplicationRegistry.getInstance().getAuthenticationManager().getMechanisms(); + + String locales = "en_US"; + + ConnectionStartBody connectionStartBody = createConnectionStartBody(pi, + locales.getBytes(), + mechanisms.getBytes(), + null); + + // Interfacing with generated code - be aware of possible changes to parameter order as versions change. + AMQFrame response = new AMQFrame((short) 0,connectionStartBody); // versionMinor + _minaProtocolSession.write(response); + } + catch (AMQException e) { - _logger.debug("Method frame received: " + frame); + _logger.error("Received incorrect protocol initiation", e); + + _minaProtocolSession.write(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion())); + + // TODO: Close connection (but how to wait until message is sent?) + // ritchiem 2006-12-04 will this not do? +// WriteFuture future = _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOLgetProtocolMajorVersion()], pv[i][PROTOCOLgetProtocolMinorVersion()])); +// future.join(); +// close connection + } + } - final AMQMethodEvent evt = new AMQMethodEvent(frame.getChannel(), - (AMQMethodBody) frame.getBodyFrame()); + private ConnectionStartBody createConnectionStartBody(ProtocolInitiation pi, + byte[] locales, + byte[] mechanisms, + FieldTable serverProperties) + { + return new ConnectionStartBodyImpl(pi._protocolMajor, pi._protocolMinor,serverProperties,mechanisms,locales); + } + + + private void methodFrameReceived(int channelId, AMQMethodBodyImpl methodBody) + { + + final AMQMethodEvent evt = new AMQMethodEvent(channelId, + methodBody); //Check that this channel is not closing - if (channelAwaitingClosure(frame.getChannel())) + if (channelAwaitingClosure(channelId)) { if ((evt.getMethod() instanceof ChannelCloseOkBody)) { if (_logger.isInfoEnabled()) { - _logger.info("Channel[" + frame.getChannel() + "] awaiting closure - processing close-ok"); + _logger.info("Channel[" + channelId + "] awaiting closure - processing close-ok"); } } else { if (_logger.isInfoEnabled()) { - _logger.info("Channel[" + frame.getChannel() + "] awaiting closure ignoring"); + _logger.info("Channel[" + channelId + "] awaiting closure ignoring"); } return; } @@ -298,19 +325,19 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, } if (!wasAnyoneInterested) { - throw new AMQException("AMQMethodEvent " + evt + " was not processed by any listener on Broker."); + throw new AMQNoMethodHandlerException(evt); } } catch (AMQChannelException e) { - if (getChannel(frame.getChannel()) != null) + if (getChannel(channelId) != null) { if (_logger.isInfoEnabled()) { _logger.info("Closing channel due to: " + e.getMessage()); } - writeFrame(e.getCloseFrame(frame.getChannel())); - closeChannel(frame.getChannel()); + writeFrame(e.getCloseFrame(channelId)); + closeChannel(channelId); } else { @@ -328,7 +355,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, AMQConstant.CHANNEL_ERROR.getName().toString()); _stateManager.changeState(AMQState.CONNECTION_CLOSING); - writeFrame(ce.getCloseFrame(frame.getChannel())); + writeFrame(ce.getCloseFrame(channelId)); } } catch (AMQConnectionException e) @@ -339,7 +366,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, } closeSession(); _stateManager.changeState(AMQState.CONNECTION_CLOSING); - writeFrame(e.getCloseFrame(frame.getChannel())); + writeFrame(e.getCloseFrame(channelId)); } } catch (Exception e) @@ -353,61 +380,21 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, } } - private void contentFrameReceived(AMQFrame frame) throws AMQException - { - if (frame.getBodyFrame() instanceof ContentHeaderBody) - { - contentHeaderReceived(frame); - } - else if (frame.getBodyFrame() instanceof ContentBody) - { - contentBodyReceived(frame); - } - else if (frame.getBodyFrame() instanceof HeartbeatBody) - { - _logger.debug("Received heartbeat from client"); - } - else - { - _logger.warn("Unrecognised frame " + frame.getClass().getName()); - } - } - private void contentHeaderReceived(AMQFrame frame) throws AMQException + private void contentHeaderReceived(int channelId, ContentHeaderBody body) throws AMQException { - if (_logger.isDebugEnabled()) - { - _logger.debug("Content header frame received: " + frame); - } - AMQChannel channel = getChannel(frame.getChannel()); + AMQChannel channel = getAndAssertChannel(channelId); + + channel.publishContentHeader(body); - if (channel == null) - { - throw new AMQException(AMQConstant.NOT_FOUND, "Channel not found with id:" + frame.getChannel()); - } - else - { - channel.publishContentHeader((ContentHeaderBody) frame.getBodyFrame()); - } } - private void contentBodyReceived(AMQFrame frame) throws AMQException + private void contentBodyReceived(int channelId, ContentBody body) throws AMQException { - if (_logger.isDebugEnabled()) - { - _logger.debug("Content body frame received: " + frame); - } - AMQChannel channel = getChannel(frame.getChannel()); + AMQChannel channel = getAndAssertChannel(channelId); - if (channel == null) - { - throw new AMQException(AMQConstant.NOT_FOUND, "Channel not found with id:" + frame.getChannel()); - } - else - { - channel.publishContentBody((ContentBody) frame.getBodyFrame(), this); - } + channel.publishContentBody(body, this); } /** @@ -437,6 +424,16 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, return new ArrayList(_channelMap.values()); } + public AMQChannel getAndAssertChannel(int channelId) throws AMQException + { + AMQChannel channel = getChannel(channelId); + if (channel == null) + { + throw new AMQException(AMQConstant.NOT_FOUND, "Channel not found with id:" + channelId); + } + return channel; + } + public AMQChannel getChannel(int channelId) throws AMQException { if (channelAwaitingClosure(channelId)) @@ -685,24 +682,26 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, private void setProtocolVersion(byte major, byte minor) { - _major = major; - _minor = minor; - _registry = MainRegistry.getVersionSpecificRegistry(major, minor); + _protocolVersion = new ProtocolVersion(major,minor); + + _registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion); + + _protocolOutputConverter = ProtocolOutputConverterRegistry.getConverter(this); } public byte getProtocolMajorVersion() { - return _major; + return _protocolVersion.getMajorVersion(); } public byte getProtocolMinorVersion() { - return _minor; + return _protocolVersion.getMinorVersion(); } public boolean isProtocolVersion(byte major, byte minor) { - return _major == major && _minor == minor; + return getProtocolMajorVersion() == major && getProtocolMinorVersion() == minor; } public VersionSpecificRegistry getRegistry() @@ -739,5 +738,14 @@ public class AMQMinaProtocolSession implements AMQProtocolSession, _taskList.remove(task); } + public ProtocolOutputConverter getProtocolOutputConverter() + { + return _protocolOutputConverter; + } + + public ProtocolVersion getProtocolVersion() + { + return _protocolVersion; + } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQNoMethodHandlerException.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQNoMethodHandlerException.java new file mode 100644 index 0000000000..82f6e96906 --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQNoMethodHandlerException.java @@ -0,0 +1,34 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol; + +import org.apache.qpid.framing.AMQMethodBodyImpl; +import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.AMQException; + +public class AMQNoMethodHandlerException extends AMQException +{ + + public AMQNoMethodHandlerException(AMQMethodEvent evt) + { + super("AMQMethodEvent " + evt + " was not processed by any listener on Broker."); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java index 9d397505dc..756a8b5ebe 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQPFastProtocolHandler.java @@ -39,7 +39,7 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; import org.apache.qpid.framing.HeartbeatBody; import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersionList; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.transport.ConnectorConfiguration; @@ -53,7 +53,7 @@ import org.apache.qpid.ssl.SSLContextFactory; * the state for the connection. * */ -public class AMQPFastProtocolHandler extends IoHandlerAdapter implements ProtocolVersionList +public class AMQPFastProtocolHandler extends IoHandlerAdapter { private static final Logger _logger = Logger.getLogger(AMQPFastProtocolHandler.class); @@ -162,12 +162,11 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter implements Protoco AMQProtocolSession session = AMQMinaProtocolSession.getAMQProtocolSession(protocolSession); if (throwable instanceof AMQProtocolHeaderException) { - /* Find last protocol version in protocol version list. Make sure last protocol version - listed in the build file (build-module.xml) is the latest version which will be returned - here. */ - int i = pv.length - 1; - protocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); + + protocolSession.write(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion())); + protocolSession.close(); + _logger.error("Error in protocol initiation " + session + ": " + throwable.getMessage(), throwable); } else if(throwable instanceof IOException) @@ -176,8 +175,6 @@ public class AMQPFastProtocolHandler extends IoHandlerAdapter implements Protoco } else { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. // Be aware of possible changes to parameter order as versions change. protocolSession.write(ConnectionCloseBody.createAMQFrame(0, session.getProtocolMajorVersion(), diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java index 503dc8b554..4cfee06850 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java @@ -28,6 +28,7 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -162,4 +163,6 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession void removeSessionCloseTask(Task task); + public ProtocolOutputConverter getProtocolOutputConverter(); + } diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java index ea89136a62..50cbc35266 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSessionMBean.java @@ -24,6 +24,7 @@ import javax.management.JMException; import javax.management.MBeanException; import javax.management.MBeanNotificationInfo; import javax.management.Notification; +import javax.management.NotCompliantMBeanException; import javax.management.monitor.MonitorNotification; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; @@ -39,6 +40,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionCloseBodyImpl; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.server.AMQChannel; import org.apache.qpid.server.management.AMQManagedObject; @@ -65,7 +67,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed new AMQShortString("Broker Management Console has closed the connection."); @MBeanConstructor("Creates an MBean exposing an AMQ Broker Connection") - public AMQProtocolSessionMBean(AMQMinaProtocolSession session) throws JMException + public AMQProtocolSessionMBean(AMQMinaProtocolSession session) throws NotCompliantMBeanException, OpenDataException { super(ManagedConnection.class, ManagedConnection.TYPE); _session = session; @@ -74,6 +76,8 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed _name = jmxEncode(new StringBuffer(remote), 0).toString(); init(); } + + static { try @@ -94,7 +98,7 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed { _channelType = new CompositeType("Channel", "Channel Details", _channelAtttibuteNames, - _channelAtttibuteNames, _channelAttributeTypes); + _channelAtttibuteNames, _channelAttributeTypes); _channelsType = new TabularType("Channels", "Channels", _channelType, _indexNames); } @@ -215,18 +219,11 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed */ public void closeConnection() throws JMException { - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame response = ConnectionCloseBody.createAMQFrame(0, - _session.getProtocolMajorVersion(), - _session.getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - AMQConstant.REPLY_SUCCESS.getCode(), // replyCode + ConnectionCloseBody connectionCloseBody = + createConnectionCloseBody(AMQConstant.REPLY_SUCCESS.getCode(), // replyCode BROKER_MANAGEMENT_CONSOLE_HAS_CLOSED_THE_CONNECTION // replyText ); - _session.writeFrame(response); + _session.writeFrame(new AMQFrame(0,connectionCloseBody)); try { @@ -238,6 +235,11 @@ public class AMQProtocolSessionMBean extends AMQManagedObject implements Managed } } + private ConnectionCloseBody createConnectionCloseBody(int code, AMQShortString replyText) + { + return new ConnectionCloseBodyImpl(code,replyText,0,0); + } + @Override public MBeanNotificationInfo[] getNotificationInfo() { diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/UnknnownMessageTypeException.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/UnknnownMessageTypeException.java new file mode 100644 index 0000000000..45d09e8f3e --- /dev/null +++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/UnknnownMessageTypeException.java @@ -0,0 +1,33 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol; + +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.AMQException; + +public class UnknnownMessageTypeException extends AMQException +{ + public UnknnownMessageTypeException(AMQDataBlock message) + { + super("Unknown message type: " + message.getClass().getName() + ": " + message); + + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java index aa7ea16afc..32873c3cf5 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQMessage.java @@ -20,23 +20,34 @@ */ package org.apache.qpid.server.queue; -import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.log4j.Logger; -import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.*; +import org.apache.qpid.framing.AMQBodyImpl; +import org.apache.qpid.framing.AMQDataBlock; +import org.apache.qpid.framing.AMQFrame; +import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.abstraction.ContentChunk; +import org.apache.qpid.framing.abstraction.MessagePublishInfo; +import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.store.MessageStore; import org.apache.qpid.server.store.StoreContext; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; -import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; -import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.server.txn.TransactionalContext; /** Combines the information that make up a deliverable message into a more manageable form. */ + +import org.apache.log4j.Logger; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Combines the information that make up a deliverable message into a more manageable form. + */ public class AMQMessage { private static final Logger _log = Logger.getLogger(AMQMessage.class); @@ -114,7 +125,7 @@ public class AMQMessage try { - AMQBody cb = getProtocolVersionMethodConverter().convertToBody(_messageHandle.getContentChunk(getStoreContext(), _messageId, ++_index)); + AMQBodyImpl cb = getProtocolVersionMethodConverter().convertToBody(_messageHandle.getContentChunk(getStoreContext(), _messageId, ++_index)); return new AMQFrame(_channel, cb); } catch (AMQException e) @@ -136,7 +147,7 @@ public class AMQMessage } } - private StoreContext getStoreContext() + public StoreContext getStoreContext() { return _txnContext.getStoreContext(); } @@ -579,6 +590,7 @@ public class AMQMessage } } +/* public void writeDeliver(AMQProtocolSession protocolSession, int channelId, long deliveryTag, AMQShortString consumerTag) throws AMQException { @@ -746,6 +758,12 @@ public class AMQMessage protocolSession.writeFrame(bodyFrameIterator.next()); } } +*/ + + public AMQMessageHandle getMessageHandle() + { + return _messageHandle; + } public long getSize() diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java index 4fd89f39da..c9329a244c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java @@ -41,9 +41,9 @@ import javax.management.openmbean.TabularType; import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.ContentBody; +import org.apache.qpid.framing.CommonContentHeaderProperties; import org.apache.qpid.framing.ContentHeaderBody; +import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.MBeanConstructor; @@ -344,12 +344,13 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que try { // Create header attributes list - BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) msg.getContentHeaderBody().properties; + CommonContentHeaderProperties headerProperties = (CommonContentHeaderProperties) msg.getContentHeaderBody().properties; String mimeType = null, encoding = null; if (headerProperties != null) { - mimeType = headerProperties.getContentType(); - encoding = headerProperties.getEncoding() == null ? "" : headerProperties.getEncoding(); + AMQShortString mimeTypeShortSting = headerProperties.getContentType(); + mimeType = mimeTypeShortSting == null ? null : mimeTypeShortSting.toString(); + encoding = headerProperties.getEncoding() == null ? "" : headerProperties.getEncoding().toString(); } Object[] itemValues = {msgId, mimeType, encoding, msgContent.toArray(new Byte[0])}; return new CompositeDataSupport(_msgContentType, _msgContentAttributes, itemValues); @@ -382,7 +383,7 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que AMQMessage msg = list.get(i - 1); ContentHeaderBody headerBody = msg.getContentHeaderBody(); // Create header attributes list - BasicContentHeaderProperties headerProperties = (BasicContentHeaderProperties) headerBody.properties; + CommonContentHeaderProperties headerProperties = (CommonContentHeaderProperties) headerBody.properties; String[] headerAttributes = headerProperties.toString().split(","); Object[] itemValues = {msg.getMessageId(), headerAttributes, headerBody.bodySize, msg.isRedelivered()}; CompositeData messageData = new CompositeDataSupport(_messageDataType, _msgAttributeNames, itemValues); diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java index 208a59516c..e70926736d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/ConcurrentSelectorDeliveryManager.java @@ -270,7 +270,8 @@ public class ConcurrentSelectorDeliveryManager implements DeliveryManager channel.addUnacknowledgedMessage(msg, deliveryTag, null, _queue); } - msg.writeGetOk(protocolSession, channel.getChannelId(), deliveryTag, _queue.getMessageCount()); + protocolSession.getProtocolOutputConverter().writeGetOk(msg, channel.getChannelId(), + deliveryTag, _queue.getMessageCount()); _totalMessageSize.addAndGet(-msg.getSize()); } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java index ede7731a06..0a2e73880c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SubscriptionImpl.java @@ -29,9 +29,9 @@ import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.common.AMQPFilterTypes; import org.apache.qpid.common.ClientProperties; import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicCancelOkBody; import org.apache.qpid.framing.FieldTable; import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.filter.FilterManager; import org.apache.qpid.server.filter.FilterManagerFactory; import org.apache.qpid.server.protocol.AMQProtocolSession; @@ -258,7 +258,7 @@ public class SubscriptionImpl implements Subscription { channel.addUnacknowledgedBrowsedMessage(msg, deliveryTag, consumerTag, queue); } - msg.writeDeliver(protocolSession, channel.getChannelId(), deliveryTag, consumerTag); + protocolSession.getProtocolOutputConverter().writeDeliver(msg, channel.getChannelId(), deliveryTag, consumerTag); } } @@ -294,7 +294,7 @@ public class SubscriptionImpl implements Subscription msg.decrementReference(storeContext); } - msg.writeDeliver(protocolSession, channel.getChannelId(), deliveryTag, consumerTag); + protocolSession.getProtocolOutputConverter().writeDeliver(msg, channel.getChannelId(), deliveryTag, consumerTag); } } @@ -466,13 +466,9 @@ public class SubscriptionImpl implements Subscription if (_autoClose && !_sentClose) { _logger.info("Closing autoclose subscription:" + this); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - protocolSession.writeFrame(BasicCancelOkBody.createAMQFrame(channel.getChannelId(), - (byte) 8, (byte) 0, // AMQP version (major, minor) - consumerTag // consumerTag - )); + ProtocolOutputConverter converter = protocolSession.getProtocolOutputConverter(); + converter.confirmConsumerAutoClose(channel.getChannelId(), consumerTag); + _sentClose = true; } } diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java index d12f5cd084..73401ee664 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java +++ b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java @@ -27,35 +27,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.BasicAckBody; -import org.apache.qpid.framing.BasicCancelBody; -import org.apache.qpid.framing.BasicConsumeBody; -import org.apache.qpid.framing.BasicGetBody; -import org.apache.qpid.framing.BasicPublishBody; -import org.apache.qpid.framing.BasicQosBody; -import org.apache.qpid.framing.BasicRecoverBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelFlowBody; -import org.apache.qpid.framing.ChannelOpenBody; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.framing.ConnectionOpenBody; -import org.apache.qpid.framing.ConnectionSecureOkBody; -import org.apache.qpid.framing.ConnectionStartOkBody; -import org.apache.qpid.framing.ConnectionTuneOkBody; -import org.apache.qpid.framing.ExchangeBoundBody; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeleteBody; -import org.apache.qpid.framing.QueueBindBody; -import org.apache.qpid.framing.QueueDeclareBody; -import org.apache.qpid.framing.QueueDeleteBody; -import org.apache.qpid.framing.QueuePurgeBody; -import org.apache.qpid.framing.TxCommitBody; -import org.apache.qpid.framing.TxRollbackBody; -import org.apache.qpid.framing.TxSelectBody; -import org.apache.qpid.framing.BasicRejectBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; import org.apache.qpid.server.handler.BasicAckMethodHandler; diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java b/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java index e3af0bc486..2f28a3125d 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java +++ b/java/broker/src/main/java/org/apache/qpid/server/state/StateAwareMethodListener.java @@ -21,6 +21,7 @@ package org.apache.qpid.server.state; import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/ContentChunkAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/store/ContentChunkAdapter.java deleted file mode 100644 index 90aa7bb998..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/store/ContentChunkAdapter.java +++ /dev/null @@ -1,57 +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.server.store; - -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.abstraction.ContentChunk; - -import org.apache.mina.common.ByteBuffer; - -public class ContentChunkAdapter -{ - public static ContentBody toConentBody(ContentChunk contentBodyChunk) - { - return new ContentBody(contentBodyChunk.getData()); - } - - public static ContentChunk toConentChunk(final ContentBody contentBodyChunk) - { - return new ContentChunk() { - - public int getSize() - { - return contentBodyChunk.getSize(); - } - - public ByteBuffer getData() - { - return contentBodyChunk.payload; - } - - public void reduceToFit() - { - contentBodyChunk.reduceBufferToFit(); - } - }; - - } - -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/store/MessagePublishInfoAdapter.java b/java/broker/src/main/java/org/apache/qpid/server/store/MessagePublishInfoAdapter.java deleted file mode 100644 index 6ee2fa784d..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/store/MessagePublishInfoAdapter.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.apache.qpid.server.store; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.BasicPublishBody; -import org.apache.qpid.framing.abstraction.MessagePublishInfo; - -public class MessagePublishInfoAdapter -{ - private final byte _majorVersion; - private final byte _minorVersion; - private final int _classId; - private final int _methodId; - - - public MessagePublishInfoAdapter(byte majorVersion, byte minorVersion) - { - _majorVersion = majorVersion; - _minorVersion = minorVersion; - _classId = BasicPublishBody.getClazz(majorVersion,minorVersion); - _methodId = BasicPublishBody.getMethod(majorVersion,minorVersion); - } - - public BasicPublishBody toMethodBody(MessagePublishInfo pubInfo) - { - return new BasicPublishBody(_majorVersion, - _minorVersion, - _classId, - _methodId, - pubInfo.getExchange(), - pubInfo.isImmediate(), - pubInfo.isMandatory(), - pubInfo.getRoutingKey(), - 0) ; // ticket - } - - public MessagePublishInfo toMessagePublishInfo(final BasicPublishBody body) - { - return new MessagePublishInfo() - { - - public AMQShortString getExchange() - { - return body.getExchange(); - } - - public boolean isImmediate() - { - return body.getImmediate(); - } - - public boolean isMandatory() - { - return body.getMandatory(); - } - - public AMQShortString getRoutingKey() - { - return body.getRoutingKey(); - } - }; - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java index 413524b6d8..1b4ae02399 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQConnection.java @@ -25,7 +25,8 @@ import org.apache.qpid.AMQException; import org.apache.qpid.AMQUndeliveredException; import org.apache.qpid.AMQUnresolvedAddressException; import org.apache.qpid.client.failover.FailoverSupport; -import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; +import org.apache.qpid.client.protocol.ProtocolOutputHandler; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.transport.TransportConnection; import org.apache.qpid.exchange.ExchangeDefaults; @@ -36,6 +37,8 @@ import org.apache.qpid.framing.ChannelOpenBody; import org.apache.qpid.framing.ChannelOpenOkBody; import org.apache.qpid.framing.TxSelectBody; import org.apache.qpid.framing.TxSelectOkBody; +import org.apache.qpid.framing.AMQMethodFactory; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.jms.ChannelLimitReachedException; import org.apache.qpid.jms.Connection; @@ -92,7 +95,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect * the handler deals with this. It also deals with the initial dispatch of any protocol frames to their appropriate * handler. */ - private AMQProtocolHandler _protocolHandler; + private AMQProtocolHandlerImpl _protocolHandler; /** Maps from session id (Integer) to AMQSession instance */ private final Map _sessions = new LinkedHashMap(); //fixme this is map is replicated in amqprotocolsession as _channelId2SessionMap @@ -273,7 +276,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _failoverPolicy = new FailoverPolicy(connectionURL); - _protocolHandler = new AMQProtocolHandler(this); + _protocolHandler = new AMQProtocolHandlerImpl(this); // We are not currently connected _connected = false; @@ -550,26 +553,15 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect private void createChannelOverWire(int channelId, int prefetchHigh, int prefetchLow, boolean transacted) throws AMQException { + // define this here, should be poassed in + final int prefetchSize = 0; - // TODO: Be aware of possible changes to parameter order as versions change. + AMQMethodFactory methodFactory = getAMQMethodFactory(); - _protocolHandler.syncWrite( - ChannelOpenBody.createAMQFrame(channelId, - _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), - null), // outOfBand - ChannelOpenOkBody.class); - - //todo send low water mark when protocol allows. - //todo Be aware of possible changes to parameter order as versions change. - _protocolHandler.syncWrite( - BasicQosBody.createAMQFrame(channelId, - _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), - false, // global - prefetchHigh, // prefetchCount - 0), // prefetchSize - BasicQosOkBody.class); + ChannelOpenBody openBody = methodFactory.createChannelOpen(); + sendCommandReceiveResponse(channelId, openBody); + AMQMethodBody qosBody = methodFactory.createMessageQos(prefetchHigh, prefetchSize); + sendCommandReceiveResponse(channelId, qosBody); if (transacted) { @@ -578,14 +570,21 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect _logger.debug("Issuing TxSelect for " + channelId); } - // TODO: Be aware of possible changes to parameter order as versions change. - _protocolHandler.syncWrite(TxSelectBody.createAMQFrame(channelId, - _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion()), - TxSelectOkBody.class); + TxSelectBody txSelectBody = methodFactory.createTxSelect(); + sendCommandReceiveResponse(channelId, txSelectBody); } } + private AMQMethodBody sendCommandReceiveResponse(int channelId, AMQMethodBody command) throws AMQException + { + return getProtocolOutputHandler().sendCommandReceiveResponse(channelId, command); + } + + private AMQMethodFactory getAMQMethodFactory() + { + return getProtocolOutputHandler().getAMQMethodFactory(); + } + private void reopenChannel(int channelId, int prefetchHigh, int prefetchLow, boolean transacted) throws AMQException { try @@ -934,7 +933,7 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect return _virtualHost; } - public AMQProtocolHandler getProtocolHandler() + public AMQProtocolHandlerImpl getProtocolHandler() { return _protocolHandler; } @@ -1218,4 +1217,9 @@ public class AMQConnection extends Closeable implements Connection, QueueConnect { _taskPool.execute(task); } + + public ProtocolOutputHandler getProtocolOutputHandler() + { + return _protocolHandler.getOutputHandler(); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java index 89f596e541..41101ff374 100644 --- a/java/client/src/main/java/org/apache/qpid/client/AMQSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/AMQSession.java @@ -59,6 +59,7 @@ import org.apache.qpid.AMQException; import org.apache.qpid.AMQUndeliveredException; import org.apache.qpid.AMQInvalidRoutingKeyException; import org.apache.qpid.AMQInvalidArgumentException; +import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.client.failover.FailoverSupport; import org.apache.qpid.client.message.AbstractJMSMessage; import org.apache.qpid.client.message.JMSBytesMessage; @@ -68,41 +69,12 @@ import org.apache.qpid.client.message.JMSStreamMessage; import org.apache.qpid.client.message.JMSTextMessage; import org.apache.qpid.client.message.MessageFactoryRegistry; import org.apache.qpid.client.message.UnprocessedMessage; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.client.protocol.BlockingMethodFrameListener; +import org.apache.qpid.client.protocol.ProtocolOutputHandler; import org.apache.qpid.client.util.FlowControllingBlockingQueue; import org.apache.qpid.common.AMQPFilterTypes; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.AccessRequestBody; -import org.apache.qpid.framing.AccessRequestOkBody; -import org.apache.qpid.framing.BasicAckBody; -import org.apache.qpid.framing.BasicConsumeBody; -import org.apache.qpid.framing.BasicConsumeOkBody; -import org.apache.qpid.framing.BasicRecoverBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelFlowBody; -import org.apache.qpid.framing.ExchangeBoundBody; -import org.apache.qpid.framing.ExchangeBoundOkBody; -import org.apache.qpid.framing.ExchangeDeclareBody; -import org.apache.qpid.framing.ExchangeDeclareOkBody; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; -import org.apache.qpid.framing.QueueBindBody; -import org.apache.qpid.framing.QueueDeclareBody; -import org.apache.qpid.framing.QueueDeleteBody; -import org.apache.qpid.framing.QueueDeleteOkBody; -import org.apache.qpid.framing.TxCommitBody; -import org.apache.qpid.framing.TxCommitOkBody; -import org.apache.qpid.framing.TxRollbackBody; -import org.apache.qpid.framing.TxRollbackOkBody; -import org.apache.qpid.framing.QueueBindOkBody; -import org.apache.qpid.framing.QueueDeclareOkBody; -import org.apache.qpid.framing.ChannelFlowOkBody; -import org.apache.qpid.framing.BasicRecoverOkBody; -import org.apache.qpid.framing.BasicRejectBody; +import org.apache.qpid.framing.*; import org.apache.qpid.jms.Session; import org.apache.qpid.protocol.AMQConstant; import org.apache.qpid.protocol.AMQMethodEvent; @@ -197,6 +169,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi private boolean _suspended; private final Object _suspensionLock = new Object(); + private static final AMQShortString CHANNEL_CLOSE_REPLY_TEXT = new AMQShortString("JMS client closing channel"); /** Responsible for decoding a message fragment and passing it to the appropriate message consumer. */ @@ -271,11 +244,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { if (message.getDeliverBody() != null) { - final BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(message.getDeliverBody().consumerTag); + final BasicMessageConsumer consumer = (BasicMessageConsumer) _consumers.get(message.getDeliverBody().getConsumerTag()); if (consumer == null) { - _logger.warn("Received a message from queue " + message.getDeliverBody().consumerTag + " without a handler - ignoring..."); + _logger.warn("Received a message from queue " + message.getDeliverBody().getConsumerTag() + " without a handler - ignoring..."); _logger.warn("Consumers that exist: " + _consumers); _logger.warn("Session hashcode: " + System.identityHashCode(this)); } @@ -513,14 +486,11 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi i.next().acknowledgeLastDelivered(); } - // Commits outstanding messages sent and outstanding acknowledgements. - // TODO: Be aware of possible changes to parameter order as versions change. - final AMQProtocolHandler handler = getProtocolHandler(); + TxCommitBody commitBody = getAMQMethodFactory().createTxCommit(); + sendCommandReceiveResponse(commitBody); + + - handler.syncWrite(TxCommitBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), - getProtocolMinorVersion()), - TxCommitOkBody.class); } catch (AMQException e) { @@ -549,8 +519,8 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi suspendChannel(true); } - _connection.getProtocolHandler().syncWrite( - TxRollbackBody.createAMQFrame(_channelId, getProtocolMajorVersion(), getProtocolMinorVersion()), TxRollbackOkBody.class); + TxRollbackBody rollbackBody = getAMQMethodFactory().createTxRollback(); + sendCommandReceiveResponse(rollbackBody); if (_dispatcher != null) { @@ -590,15 +560,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { getProtocolHandler().closeSession(this); - // TODO: Be aware of possible changes to parameter order as versions change. - final AMQFrame frame = ChannelCloseBody.createAMQFrame(getChannelId(), - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - new AMQShortString("JMS client closing channel")); // replyText - - getProtocolHandler().syncWrite(frame, ChannelCloseOkBody.class, timeout); + ChannelCloseBody closeBody = getAMQMethodFactory().createChannelClose(AMQConstant.REPLY_SUCCESS.getCode(), // replyCode + CHANNEL_CLOSE_REPLY_TEXT); + sendCommandReceiveResponse(closeBody, timeout); + + + // When control resumes at this point, a reply will have been received that // indicates the broker has closed the channel successfully @@ -617,21 +584,17 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi } } - private AMQProtocolHandler getProtocolHandler() + private AMQProtocolHandlerImpl getProtocolHandler() { return _connection.getProtocolHandler(); } - - private byte getProtocolMinorVersion() + public ProtocolOutputHandler getProtocolOutputHandler() { - return getProtocolHandler().getProtocolMinorVersion(); + return _connection.getProtocolOutputHandler(); } - private byte getProtocolMajorVersion() - { - return getProtocolHandler().getProtocolMajorVersion(); - } + /** @@ -835,14 +798,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi consumer.clearUnackedMessages(); } - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - _connection.getProtocolHandler().syncWrite(BasicRecoverBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), - getProtocolMinorVersion(), - false) // requeue - , BasicRecoverOkBody.class); + final boolean requeue = false; + AMQMethodBody recoverBody = getAMQMethodFactory().createRecover(requeue); + sendCommandReceiveResponse(recoverBody); + + + if (_dispatcher != null) { @@ -1226,136 +1187,60 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public void declareExchange(AMQShortString name, AMQShortString type) throws AMQException { - declareExchange(name, type, getProtocolHandler()); + ExchangeDeclareBody exchangeDeclare = getAMQMethodFactory().createExchangeDeclare(name,type,getTicket()); + sendCommandReceiveResponse(exchangeDeclare); } public void declareExchangeSynch(AMQShortString name, AMQShortString type) throws AMQException { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame frame = ExchangeDeclareBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - null, // arguments - false, // autoDelete - false, // durable - name, // exchange - false, // internal - false, // nowait - false, // passive - getTicket(), // ticket - type); // type - getProtocolHandler().syncWrite(frame, ExchangeDeclareOkBody.class); - } + ExchangeDeclareBody exchangeDeclare = getAMQMethodFactory().createExchangeDeclare(name,type,getTicket()); + sendCommandReceiveResponse(exchangeDeclare); - private void declareExchange(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException - { - declareExchange(amqd.getExchangeName(), amqd.getExchangeClass(), protocolHandler); - } - - private void declareExchange(AMQShortString name, AMQShortString type, AMQProtocolHandler protocolHandler) throws AMQException - { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame exchangeDeclare = ExchangeDeclareBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - null, // arguments - false, // autoDelete - false, // durable - name, // exchange - false, // internal - false, // nowait - false, // passive - getTicket(), // ticket - type); // type - - protocolHandler.syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class); } - public void createQueue(AMQShortString name, boolean autoDelete, boolean durable, boolean exclusive) throws AMQException { - AMQFrame queueDeclare = QueueDeclareBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - null, // arguments - autoDelete, // autoDelete - durable, // durable - exclusive, // exclusive - false, // nowait - false, // passive - name, // queue - getTicket()); // ticket - - getProtocolHandler().syncWrite(queueDeclare, QueueDeclareOkBody.class); - + QueueDeclareBody queueDeclare = getAMQMethodFactory().createQueueDeclare(name, null, autoDelete, durable, exclusive, false ,getTicket()); + sendCommandReceiveResponse(queueDeclare); } public void bindQueue(AMQShortString queueName, AMQShortString routingKey, FieldTable arguments, AMQShortString exchangeName) throws AMQException { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame queueBind = QueueBindBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - arguments, // arguments - exchangeName, // exchange - false, // nowait - queueName, // queue - routingKey, // routingKey - getTicket()); // ticket - - - getProtocolHandler().syncWrite(queueBind, QueueBindOkBody.class); + QueueBindBody queueBind = getAMQMethodFactory().createQueueBind(queueName,exchangeName,routingKey,arguments,getTicket()); + sendCommandReceiveResponse(queueBind); } /** * Declare the queue. * * @param amqd - * @param protocolHandler * * @return the queue name. This is useful where the broker is generating a queue name on behalf of the client. * * @throws AMQException */ - private AMQShortString declareQueue(AMQDestination amqd, AMQProtocolHandler protocolHandler) throws AMQException + private AMQShortString declareQueue(AMQDestination amqd) throws AMQException { // For queues (but not topics) we generate the name in the client rather than the // server. This allows the name to be reused on failover if required. In general, // the destination indicates whether it wants a name generated or not. if (amqd.isNameRequired()) { - amqd.setQueueName(protocolHandler.generateQueueName()); + amqd.setQueueName(getProtocolHandler().generateQueueName()); } //TODO verify the destiation is valid. else throw - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame queueDeclare = QueueDeclareBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - null, // arguments - amqd.isAutoDelete(), // autoDelete - amqd.isDurable(), // durable - amqd.isExclusive(), // exclusive - false, // nowait - false, // passive - amqd.getAMQQueueName(), // queue - getTicket()); // ticket - - protocolHandler.syncWrite(queueDeclare, QueueDeclareOkBody.class); + createQueue(amqd.getAMQQueueName(),amqd.isAutoDelete(),amqd.isDurable(),amqd.isExclusive()); + + return amqd.getAMQQueueName(); } - private void bindQueue(AMQDestination amqd, AMQShortString queueName, AMQProtocolHandler protocolHandler, FieldTable ft) throws AMQException + private void bindQueue(AMQDestination amqd, AMQShortString queueName, FieldTable ft) throws AMQException { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame queueBind = QueueBindBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - ft, // arguments - amqd.getExchangeName(), // exchange - false, // nowait - queueName, // queue - amqd.getRoutingKey(), // routingKey - getTicket()); // ticket - - - protocolHandler.syncWrite(queueBind, QueueBindOkBody.class); + bindQueue(queueName,amqd.getRoutingKey(),ft,amqd.getExchangeName()); } /** @@ -1365,8 +1250,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi * * @return the consumer tag generated by the broker */ - private void consumeFromQueue(BasicMessageConsumer consumer, AMQShortString queueName, AMQProtocolHandler protocolHandler, - boolean nowait, String messageSelector) throws AMQException + private void consumeFromQueue(BasicMessageConsumer consumer, AMQShortString queueName, boolean nowait, String messageSelector) throws AMQException { //fixme prefetch values are not used here. Do we need to have them as parametsrs? //need to generate a consumer tag on the client so we can exploit the nowait flag @@ -1392,25 +1276,24 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi try { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame jmsConsume = BasicConsumeBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - arguments, // arguments - tag, // consumerTag - consumer.isExclusive(), // exclusive - consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE, // noAck - consumer.isNoLocal(), // noLocal - nowait, // nowait - queueName, // queue - getTicket()); // ticket - if (nowait) + final boolean noAck = consumer.getAcknowledgeMode() == Session.NO_ACKNOWLEDGE; + + AMQMethodBody consumeBody = getAMQMethodFactory().createConsumer(tag, + queueName, + arguments, + noAck, + consumer.isExclusive(), + consumer.isNoLocal(), + getTicket()); + if(nowait) { - protocolHandler.writeFrame(jmsConsume); + sendCommand(consumeBody); } else { - protocolHandler.syncWrite(jmsConsume, BasicConsumeOkBody.class); + sendCommandReceiveResponse(consumeBody); } + } catch (AMQException e) { @@ -1606,15 +1489,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { try { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame queueDeleteFrame = QueueDeleteBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - false, // ifEmpty - false, // ifUnused - true, // nowait - queueName, // queue - getTicket()); // ticket - getProtocolHandler().syncWrite(queueDeleteFrame, QueueDeleteOkBody.class); + + QueueDeleteBody deleteBody = getAMQMethodFactory().createQueueDelete(queueName, false, false, getTicket()); + sendCommandReceiveResponse(deleteBody); } catch (AMQException e) { @@ -1697,23 +1574,23 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi boolean isQueueBound(AMQShortString exchangeName, AMQShortString queueName, AMQShortString routingKey) throws JMSException { - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame boundFrame = ExchangeBoundBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - exchangeName, // exchange - queueName, // queue - routingKey); // routingKey AMQMethodEvent response = null; try { - response = getProtocolHandler().syncWrite(boundFrame, ExchangeBoundOkBody.class); + ExchangeBoundBody exchangeBoundBody = + getAMQMethodFactory().createExchangeBound(exchangeName, // exchange + queueName, // queue + routingKey); // routingKey + + + ExchangeBoundOkBody responseBody = sendCommandReceiveResponse(exchangeBoundBody, ExchangeBoundOkBody.class); + return (responseBody.getReplyCode() == 0); } catch (AMQException e) { throw new JMSAMQException(e); } - ExchangeBoundOkBody responseBody = (ExchangeBoundOkBody) response.getMethod(); - return (responseBody.replyCode == 0); //ExchangeBoundHandler.OK); Remove Broker compile dependency + } private void checkTransacted() throws JMSException @@ -1770,13 +1647,13 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi // Bounced message is processed here, away from the mina thread AbstractJMSMessage bouncedMessage = _messageFactoryRegistry.createMessage(0, false, - message.getBounceBody().exchange, - message.getBounceBody().routingKey, + message.getBounceBody().getExchange(), + message.getBounceBody().getRoutingKey(), message.getContentHeader(), message.getBodies()); - AMQConstant errorCode = AMQConstant.getConstant(message.getBounceBody().replyCode); - AMQShortString reason = message.getBounceBody().replyText; + AMQConstant errorCode = AMQConstant.getConstant(message.getBounceBody().getReplyCode()); + AMQShortString reason = message.getBounceBody().getReplyText(); _logger.debug("Message returned with error code " + errorCode + " (" + reason + ")"); //@TODO should this be moved to an exception handler of sorts. Somewhere errors are converted to correct execeptions. @@ -1812,16 +1689,12 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi */ public void acknowledgeMessage(long deliveryTag, boolean multiple) { - // TODO: Be aware of possible changes to parameter order as versions change. - final AMQFrame ackFrame = BasicAckBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), getProtocolMinorVersion(), // AMQP version (major, minor) - deliveryTag, // deliveryTag - multiple); // multiple + AMQMethodBody ackBody = getAMQMethodFactory().createAcknowledge(deliveryTag, multiple); if (_logger.isDebugEnabled()) { _logger.debug("Sending ack for delivery tag " + deliveryTag + " on channel " + _channelId); } - getProtocolHandler().writeFrame(ackFrame); + sendCommand(ackBody); } public int getDefaultPrefetch() @@ -1908,17 +1781,15 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { AMQDestination amqd = consumer.getDestination(); - AMQProtocolHandler protocolHandler = getProtocolHandler(); - - declareExchange(amqd, protocolHandler); + declareExchange(amqd.getExchangeName(), amqd.getExchangeClass()); - AMQShortString queueName = declareQueue(amqd, protocolHandler); + AMQShortString queueName = declareQueue(amqd); - bindQueue(amqd, queueName, protocolHandler, consumer.getRawSelectorFieldTable()); + bindQueue(amqd, queueName, consumer.getRawSelectorFieldTable()); try { - consumeFromQueue(consumer, queueName, protocolHandler, nowait, consumer.getMessageSelector()); + consumeFromQueue(consumer, queueName, nowait, consumer.getMessageSelector()); } catch (JMSException e) //thrown by getMessageSelector { @@ -2019,14 +1890,9 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi _suspended = suspend; - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame channelFlowFrame = ChannelFlowBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), - getProtocolMinorVersion(), - !suspend); // active + AMQMethodBody flowBody = getAMQMethodFactory().createChannelFlow(!suspend); + sendCommandReceiveResponse(flowBody); - _connection.getProtocolHandler().syncWrite(channelFlowFrame, ChannelFlowOkBody.class); } } @@ -2118,32 +1984,15 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public void requestAccess(AMQShortString realm, boolean exclusive, boolean passive, boolean active, boolean write, boolean read) throws AMQException { - getProtocolHandler().writeCommandFrameAndWaitForReply(AccessRequestBody.createAMQFrame(getChannelId(), - getProtocolMajorVersion(), - getProtocolMinorVersion(), - active, - exclusive, - passive, - read, - realm, - write), - new BlockingMethodFrameListener(_channelId) - { - public boolean processMethod(int channelId, AMQMethodBody frame) throws AMQException - { - if (frame instanceof AccessRequestOkBody) - { - setTicket(((AccessRequestOkBody) frame).getTicket()); - return true; - } - else - { - return false; - } - } - }); + AccessRequestBody accessRequest = getAMQMethodFactory().createAccessRequest(active,exclusive,passive,read,realm,write); + AccessRequestOkBody okBody = getProtocolOutputHandler().sendCommandReceiveResponse(_channelId,accessRequest, AccessRequestOkBody.class ); + setTicket(okBody.getTicket()); + } + AMQMethodFactory getAMQMethodFactory() + { + return getProtocolOutputHandler().getAMQMethodFactory(); } private class SuspenderRunner implements Runnable @@ -2187,7 +2036,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi { UnprocessedMessage message = (UnprocessedMessage) messages.next(); - if (consumerTag == null || message.getDeliverBody().consumerTag.equals(consumerTag)) + if (consumerTag == null || message.getDeliverBody().getConsumerTag().equals(consumerTag)) { if (_logger.isTraceEnabled()) { @@ -2196,7 +2045,7 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi messages.remove(); - rejectMessage(message.getDeliverBody().deliveryTag, requeue); + rejectMessage(message.getDeliverBody().getDeliveryTag(), requeue); _logger.debug("Rejected the message(" + message.getDeliverBody() + ") for consumer :" + consumerTag); } @@ -2209,13 +2058,27 @@ public class AMQSession extends Closeable implements Session, QueueSession, Topi public void rejectMessage(long deliveryTag, boolean requeue) { - AMQFrame basicRejectBody = BasicRejectBody.createAMQFrame(_channelId, - getProtocolMajorVersion(), - getProtocolMinorVersion(), - deliveryTag, - requeue); + AMQMethodBody rejectBody = getAMQMethodFactory().createRejectBody(deliveryTag, requeue); + sendCommand(rejectBody); + + } - _connection.getProtocolHandler().writeFrame(basicRejectBody); + T sendCommandReceiveResponse(AMQMethodBody command, Class responseClass) throws AMQException + { + return getProtocolOutputHandler().sendCommandReceiveResponse(_channelId, command, responseClass); + } + AMQMethodBody sendCommandReceiveResponse(AMQMethodBody command) throws AMQException + { + return getProtocolOutputHandler().sendCommandReceiveResponse(_channelId, command); + } + AMQMethodBody sendCommandReceiveResponse(AMQMethodBody command, long timeout) throws AMQException + { + return getProtocolOutputHandler().sendCommandReceiveResponse(_channelId, command, timeout); } + + void sendCommand(AMQMethodBody command) + { + getProtocolOutputHandler().sendCommand(_channelId, command); + } } diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java index e9b914425a..f0bea6cc90 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageConsumer.java @@ -33,6 +33,7 @@ import javax.jms.MessageListener; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; +import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.client.message.AbstractJMSMessage; import org.apache.qpid.client.message.MessageFactoryRegistry; import org.apache.qpid.client.message.UnprocessedMessage; @@ -42,6 +43,8 @@ import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.BasicCancelBody; import org.apache.qpid.framing.BasicCancelOkBody; import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.AMQMethodFactory; +import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.jms.MessageConsumer; import org.apache.qpid.jms.Session; @@ -438,16 +441,10 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer { if (sendClose) { - // TODO: Be aware of possible changes to parameter order as versions change. - final AMQFrame cancelFrame = BasicCancelBody.createAMQFrame(_channelId, - _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), - _consumerTag, // consumerTag - false); // nowait - try { - _protocolHandler.syncWrite(cancelFrame, BasicCancelOkBody.class); + AMQMethodBody cancelBody = getAMQMethodFactory().createConsumerCancel(_consumerTag); + sendCommandReceiveResponse(cancelBody); } catch (AMQException e) { @@ -467,6 +464,16 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer } } + private AMQMethodBody sendCommandReceiveResponse(AMQMethodBody cancelBody) throws AMQException + { + return getSession().sendCommandReceiveResponse(cancelBody); + } + + private AMQMethodFactory getAMQMethodFactory() + { + return getSession().getAMQMethodFactory(); + } + /** * Called when you need to invalidate a consumer. Used for example when failover has occurred and the client has * vetoed automatic resubscription. The caller must hold the failover mutex. @@ -490,14 +497,14 @@ public class BasicMessageConsumer extends Closeable implements MessageConsumer if (debug) { - _logger.debug("notifyMessage called with message number " + messageFrame.getDeliverBody().deliveryTag); + _logger.debug("notifyMessage called with message number " + messageFrame.getDeliverBody().getDeliveryTag()); } try { - AbstractJMSMessage jmsMessage = _messageFactory.createMessage(messageFrame.getDeliverBody().deliveryTag, - messageFrame.getDeliverBody().redelivered, - messageFrame.getDeliverBody().exchange, - messageFrame.getDeliverBody().routingKey, + AbstractJMSMessage jmsMessage = _messageFactory.createMessage(messageFrame.getDeliverBody().getDeliveryTag(), + messageFrame.getDeliverBody().getRedelivered(), + messageFrame.getDeliverBody().getExchange(), + messageFrame.getDeliverBody().getRoutingKey(), messageFrame.getContentHeader(), messageFrame.getBodies()); diff --git a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java index b01e087ce1..43b9f3569a 100644 --- a/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java +++ b/java/client/src/main/java/org/apache/qpid/client/BasicMessageProducer.java @@ -38,17 +38,11 @@ import javax.jms.Topic; import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; +import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.client.message.AbstractJMSMessage; import org.apache.qpid.client.message.MessageConverter; -import org.apache.qpid.client.protocol.AMQProtocolHandler; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.BasicConsumeBody; -import org.apache.qpid.framing.BasicContentHeaderProperties; -import org.apache.qpid.framing.BasicPublishBody; -import org.apache.qpid.framing.CompositeAMQDataBlock; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.ExchangeDeclareBody; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; +import org.apache.qpid.framing.*; public class BasicMessageProducer extends Closeable implements org.apache.qpid.jms.MessageProducer { @@ -91,7 +85,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j */ private String _mimeType; - private AMQProtocolHandler _protocolHandler; + private AMQProtocolHandlerImpl _protocolHandler; /** * True if this producer was created from a transacted session @@ -121,7 +115,7 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j private static final ContentBody[] NO_CONTENT_BODIES = new ContentBody[0]; protected BasicMessageProducer(AMQConnection connection, AMQDestination destination, boolean transacted, int channelId, - AMQSession session, AMQProtocolHandler protocolHandler, long producerId, + AMQSession session, AMQProtocolHandlerImpl protocolHandler, long producerId, boolean immediate, boolean mandatory, boolean waitUntilSent) { _connection = connection; @@ -152,20 +146,28 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j private void declareDestination(AMQDestination destination) { // Declare the exchange - // Note that the durable and internal arguments are ignored since passive is set to false - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame declare = - ExchangeDeclareBody.createAMQFrame(_channelId, _protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion(), null, // arguments - false, // autoDelete - false, // durable - destination.getExchangeName(), // exchange - false, // internal - true, // nowait - false, // passive - _session.getTicket(), // ticket - destination.getExchangeClass()); // type - _protocolHandler.writeFrame(declare); + + ExchangeDeclareBody exchangeDeclareBody = + getAMQMethodFactory().createExchangeDeclare(destination.getExchangeName(), + destination.getExchangeClass(), + _session.getTicket()); + sendCommand(exchangeDeclareBody); + + } + + private void sendCommand(AMQMethodBody command) + { + getSession().sendCommand(command); + } + + private AMQMethodBody sendCommandReceiveResponse(AMQMethodBody command) throws AMQException + { + return getSession().sendCommandReceiveResponse(command); + } + + private AMQMethodFactory getAMQMethodFactory() + { + return getSession().getAMQMethodFactory(); } public void setDisableMessageID(boolean b) throws JMSException @@ -467,21 +469,9 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j message.getJmsHeaders().setInteger(CustomJMSXProperty.JMS_QPID_DESTTYPE.getShortStringName(), type); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame publishFrame = - BasicPublishBody.createAMQFrame( - _channelId, _protocolHandler.getProtocolMajorVersion(), _protocolHandler.getProtocolMinorVersion(), - destination.getExchangeName(), // exchange - immediate, // immediate - mandatory, // mandatory - destination.getRoutingKey(), // routingKey - _session.getTicket()); // ticket - message.prepareForSending(); ByteBuffer payload = message.getData(); - BasicContentHeaderProperties contentHeaderProperties = message.getContentHeaderProperties(); + CommonContentHeaderProperties contentHeaderProperties = message.getContentHeaderProperties(); if (!_disableTimestamps) { @@ -501,37 +491,15 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j contentHeaderProperties.setDeliveryMode((byte) deliveryMode); contentHeaderProperties.setPriority((byte) priority); - final int size = (payload != null) ? payload.limit() : 0; - final int contentBodyFrameCount = calculateContentBodyFrameCount(payload); - final AMQFrame[] frames = new AMQFrame[2 + contentBodyFrameCount]; + getSession().getProtocolOutputHandler().publishMessage(getSession().getChannelId(), + destination.getExchangeName(), + destination.getRoutingKey(), + immediate, + mandatory, + payload, + contentHeaderProperties, + getSession().getTicket()); - if (payload != null) - { - createContentBodies(payload, frames, 2, _channelId); - } - - if ((contentBodyFrameCount != 0) && _logger.isDebugEnabled()) - { - _logger.debug("Sending content body frames to " + destination); - } - - // weight argument of zero indicates no child content headers, just bodies - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - AMQFrame contentHeaderFrame = - ContentHeaderBody.createAMQFrame(_channelId, - BasicConsumeBody.getClazz(_protocolHandler.getProtocolMajorVersion(), - _protocolHandler.getProtocolMinorVersion()), 0, - contentHeaderProperties, size); - if (_logger.isDebugEnabled()) - { - _logger.debug("Sending content header frame to " + destination); - } - - frames[0] = publishFrame; - frames[1] = contentHeaderFrame; - CompositeAMQDataBlock compositeFrame = new CompositeAMQDataBlock(frames); - _protocolHandler.writeFrame(compositeFrame, wait); if (message != origMessage) { @@ -544,6 +512,8 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j } } + + private void checkTemporaryDestination(AMQDestination destination) throws JMSException { if (destination instanceof TemporaryDestination) @@ -564,59 +534,6 @@ public class BasicMessageProducer extends Closeable implements org.apache.qpid.j } } - /** - * Create content bodies. This will split a large message into numerous bodies depending on the negotiated - * maximum frame size. - * - * @param payload - * @param frames - * @param offset - * @param channelId @return the array of content bodies - */ - private void createContentBodies(ByteBuffer payload, AMQFrame[] frames, int offset, int channelId) - { - - if (frames.length == (offset + 1)) - { - frames[offset] = ContentBody.createAMQFrame(channelId, new ContentBody(payload)); - } - else - { - - final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize() - 1; - long remaining = payload.remaining(); - for (int i = offset; i < frames.length; i++) - { - payload.position((int) framePayloadMax * (i - offset)); - int length = (remaining >= framePayloadMax) ? (int) framePayloadMax : (int) remaining; - payload.limit(payload.position() + length); - frames[i] = ContentBody.createAMQFrame(channelId, new ContentBody(payload.slice())); - - remaining -= length; - } - } - - } - - private int calculateContentBodyFrameCount(ByteBuffer payload) - { - // we substract one from the total frame maximum size to account for the end of frame marker in a body frame - // (0xCE byte). - int frameCount; - if ((payload == null) || (payload.remaining() == 0)) - { - frameCount = 0; - } - else - { - int dataLength = payload.remaining(); - final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize() - 1; - int lastFrame = ((dataLength % framePayloadMax) > 0) ? 1 : 0; - frameCount = (int) (dataLength / framePayloadMax) + lastFrame; - } - - return frameCount; - } public void setMimeType(String mimeType) throws JMSException { diff --git a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java index 844ecbe743..268456290e 100644 --- a/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java @@ -25,7 +25,7 @@ import java.util.concurrent.CountDownLatch; import org.apache.log4j.Logger; import org.apache.mina.common.IoSession; import org.apache.qpid.AMQDisconnectedException; -import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; import org.apache.qpid.client.state.AMQStateManager; /** @@ -42,7 +42,7 @@ public class FailoverHandler implements Runnable private static final Logger _logger = Logger.getLogger(FailoverHandler.class); private final IoSession _session; - private AMQProtocolHandler _amqProtocolHandler; + private AMQProtocolHandlerImpl _amqProtocolHandler; /** * Used where forcing the failover host @@ -54,7 +54,7 @@ public class FailoverHandler implements Runnable */ private int _port; - public FailoverHandler(AMQProtocolHandler amqProtocolHandler, IoSession session) + public FailoverHandler(AMQProtocolHandlerImpl amqProtocolHandler, IoSession session) { _amqProtocolHandler = amqProtocolHandler; _session = session; diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java deleted file mode 100644 index 9bd0205977..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicCancelOkMethodHandler.java +++ /dev/null @@ -1,54 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.BasicCancelOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -/** - * @author Apache Software Foundation - */ -public class BasicCancelOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(BasicCancelOkMethodHandler.class); - private static final BasicCancelOkMethodHandler _instance = new BasicCancelOkMethodHandler(); - - public static BasicCancelOkMethodHandler getInstance() - { - return _instance; - } - - private BasicCancelOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.debug("New BasicCancelOk method received"); - BasicCancelOkBody body = (BasicCancelOkBody) evt.getMethod(); - protocolSession.confirmConsumerCancelled(evt.getChannelId(), body.consumerTag); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java deleted file mode 100644 index d34d6688c1..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicDeliverMethodHandler.java +++ /dev/null @@ -1,49 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.BasicDeliverBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class BasicDeliverMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(BasicDeliverMethodHandler.class); - - private static final BasicDeliverMethodHandler _instance = new BasicDeliverMethodHandler(); - - public static BasicDeliverMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(), (BasicDeliverBody) evt.getMethod()); - _logger.debug("New JmsDeliver method received"); - protocolSession.unprocessedMessageReceived(msg); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java deleted file mode 100644 index 02573c5d00..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/BasicReturnMethodHandler.java +++ /dev/null @@ -1,50 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.message.UnprocessedMessage; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.BasicReturnBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class BasicReturnMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(BasicReturnMethodHandler.class); - - private static final BasicReturnMethodHandler _instance = new BasicReturnMethodHandler(); - - public static BasicReturnMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.debug("New JmsBounce method received"); - final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(),(BasicReturnBody)evt.getMethod()); - - protocolSession.unprocessedMessageReceived(msg); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java deleted file mode 100644 index e2b101ab79..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseMethodHandler.java +++ /dev/null @@ -1,99 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQChannelClosedException; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQInvalidRoutingKeyException; -import org.apache.qpid.client.AMQNoConsumersException; -import org.apache.qpid.client.AMQNoRouteException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ChannelCloseMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ChannelCloseMethodHandler.class); - - private static ChannelCloseMethodHandler _handler = new ChannelCloseMethodHandler(); - - public static ChannelCloseMethodHandler getInstance() - { - return _handler; - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.debug("ChannelClose method received"); - ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); - - AMQConstant errorCode = AMQConstant.getConstant(method.replyCode); - AMQShortString reason = method.replyText; - if (_logger.isDebugEnabled()) - { - _logger.debug("Channel close reply code: " + errorCode + ", reason: " + reason); - } - - // TODO: Be aware of possible changes to parameter order as versions change. - AMQFrame frame = ChannelCloseOkBody.createAMQFrame(evt.getChannelId(), method.getMajor(), method.getMinor()); - protocolSession.writeFrame(frame); - if (errorCode != AMQConstant.REPLY_SUCCESS) - { - if (_logger.isDebugEnabled()) - { - _logger.debug("Channel close received with errorCode " + errorCode + ", and reason " + reason); - } - if (errorCode == AMQConstant.NO_CONSUMERS) - { - throw new AMQNoConsumersException("Error: " + reason, null); - } - else if (errorCode == AMQConstant.NO_ROUTE) - { - throw new AMQNoRouteException("Error: " + reason, null); - } - else if (errorCode == AMQConstant.INVALID_ARGUMENT) - { - _logger.debug("Broker responded with Invalid Argument."); - - throw new org.apache.qpid.AMQInvalidArgumentException(String.valueOf(reason)); - } - else if (errorCode == AMQConstant.INVALID_ROUTING_KEY) - { - _logger.debug("Broker responded with Invalid Routing Key."); - - throw new AMQInvalidRoutingKeyException(String.valueOf(reason)); - } - else - { - throw new AMQChannelClosedException(errorCode, "Error: " + reason); - } - - } - protocolSession.channelClosed(evt.getChannelId(), errorCode, String.valueOf(reason)); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java deleted file mode 100644 index 794071cc34..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelCloseOkMethodHandler.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ChannelCloseOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ChannelCloseOkMethodHandler.class); - - private static final ChannelCloseOkMethodHandler _instance = new ChannelCloseOkMethodHandler(); - - public static ChannelCloseOkMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.info("Received channel-close-ok for channel-id " + evt.getChannelId()); - - //todo this should do the closure - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java deleted file mode 100644 index 1f003649c0..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ChannelFlowOkMethodHandler.java +++ /dev/null @@ -1,50 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ChannelFlowOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ChannelFlowOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ChannelFlowOkMethodHandler.class); - private static final ChannelFlowOkMethodHandler _instance = new ChannelFlowOkMethodHandler(); - - public static ChannelFlowOkMethodHandler getInstance() - { - return _instance; - } - - private ChannelFlowOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - ChannelFlowOkBody method = (ChannelFlowOkBody) evt.getMethod(); - _logger.debug("Received Channel.Flow-Ok message, active = " + method.active); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java deleted file mode 100644 index 9c8e9188ec..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionCloseMethodHandler.java +++ /dev/null @@ -1,100 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQConnectionClosedException; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQAuthenticationException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ConnectionCloseMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ConnectionCloseMethodHandler.class); - - private static ConnectionCloseMethodHandler _handler = new ConnectionCloseMethodHandler(); - - public static ConnectionCloseMethodHandler getInstance() - { - return _handler; - } - - private ConnectionCloseMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.info("ConnectionClose frame received"); - ConnectionCloseBody method = (ConnectionCloseBody) evt.getMethod(); - - // does it matter - //stateManager.changeState(AMQState.CONNECTION_CLOSING); - - AMQConstant errorCode = AMQConstant.getConstant(method.replyCode); - AMQShortString reason = method.replyText; - - try - { - // TODO: check whether channel id of zero is appropriate - // Be aware of possible changes to parameter order as versions change. - protocolSession.writeFrame(ConnectionCloseOkBody.createAMQFrame((short) 0, method.getMajor(), method.getMinor())); - - if (errorCode != AMQConstant.REPLY_SUCCESS) - { - if (errorCode == AMQConstant.NOT_ALLOWED) - { - _logger.info("Authentication Error:" + Thread.currentThread().getName()); - - protocolSession.closeProtocolSession(); - - //todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state. - stateManager.changeState(AMQState.CONNECTION_NOT_STARTED); - - throw new AMQAuthenticationException(errorCode, reason == null ? null : reason.toString()); - } - else - { - _logger.info("Connection close received with error code " + errorCode); - - - throw new AMQConnectionClosedException(errorCode, "Error: " + reason); - } - } - } - finally - { - // this actually closes the connection in the case where it is not an error. - - protocolSession.closeProtocolSession(); - - stateManager.changeState(AMQState.CONNECTION_CLOSED); - } - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java deleted file mode 100644 index 2e0f273c32..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionOpenOkMethodHandler.java +++ /dev/null @@ -1,48 +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.client.handler; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener -{ - private static final ConnectionOpenOkMethodHandler _instance = new ConnectionOpenOkMethodHandler(); - - public static ConnectionOpenOkMethodHandler getInstance() - { - return _instance; - } - - private ConnectionOpenOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - stateManager.changeState(AMQState.CONNECTION_OPEN); - } - -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java deleted file mode 100644 index 866f65b384..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionRedirectMethodHandler.java +++ /dev/null @@ -1,70 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ConnectionRedirectBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ConnectionRedirectMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ConnectionRedirectMethodHandler.class); - - private static final int DEFAULT_REDIRECT_PORT = 5672; - - private static ConnectionRedirectMethodHandler _handler = new ConnectionRedirectMethodHandler(); - - public static ConnectionRedirectMethodHandler getInstance() - { - return _handler; - } - - private ConnectionRedirectMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.info("ConnectionRedirect frame received"); - ConnectionRedirectBody method = (ConnectionRedirectBody) evt.getMethod(); - - String host = method.host.toString(); - // the host is in the form hostname:port with the port being optional - int portIndex = host.indexOf(':'); - - int port; - if (portIndex == -1) - { - port = DEFAULT_REDIRECT_PORT; - } - else - { - port = Integer.parseInt(host.substring(portIndex + 1)); - host = host.substring(0, portIndex); - - } - protocolSession.failover(host, port); - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java deleted file mode 100644 index ab6acffeaf..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionSecureMethodHandler.java +++ /dev/null @@ -1,73 +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.client.handler; - -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.ConnectionSecureBody; -import org.apache.qpid.framing.ConnectionSecureOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ConnectionSecureMethodHandler implements StateAwareMethodListener -{ - private static final ConnectionSecureMethodHandler _instance = new ConnectionSecureMethodHandler(); - - public static ConnectionSecureMethodHandler getInstance() - { - return _instance; - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - SaslClient client = protocolSession.getSaslClient(); - if (client == null) - { - throw new AMQException("No SASL client set up - cannot proceed with authentication"); - } - - ConnectionSecureBody body = (ConnectionSecureBody) evt.getMethod(); - - try - { - // Evaluate server challenge - byte[] response = client.evaluateChallenge(body.challenge); - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - AMQFrame responseFrame = ConnectionSecureOkBody.createAMQFrame(evt.getChannelId(), - body.getMajor(), body.getMinor(), - response); // response - protocolSession.writeFrame(responseFrame); - } - catch (SaslException e) - { - throw new AMQException("Error processing SASL challenge: " + e, e); - } - - - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java deleted file mode 100644 index 2aa2c1872b..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionStartMethodHandler.java +++ /dev/null @@ -1,261 +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.client.handler; - -import java.io.UnsupportedEncodingException; -import java.util.HashSet; -import java.util.StringTokenizer; - -import javax.security.sasl.Sasl; -import javax.security.sasl.SaslClient; -import javax.security.sasl.SaslException; - -import org.apache.log4j.Logger; - -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.security.AMQCallbackHandler; -import org.apache.qpid.client.security.CallbackHandlerRegistry; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.common.ClientProperties; -import org.apache.qpid.common.QpidProperties; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionStartBody; -import org.apache.qpid.framing.ConnectionStartOkBody; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; -import org.apache.qpid.framing.ProtocolVersionList; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ConnectionStartMethodHandler implements StateAwareMethodListener -{ - private static final Logger _log = Logger.getLogger(ConnectionStartMethodHandler.class); - - private static final ConnectionStartMethodHandler _instance = new ConnectionStartMethodHandler(); - - public static ConnectionStartMethodHandler getInstance() - { - return _instance; - } - - private ConnectionStartMethodHandler() - { } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) - throws AMQException - { - _log.debug("public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, " - + "AMQMethodEvent evt): called"); - - ConnectionStartBody body = (ConnectionStartBody) evt.getMethod(); - - byte major = (byte) body.versionMajor; - byte minor = (byte) body.versionMinor; - boolean versionOk = false; - - // For the purposes of interop, we can make the client accept the broker's version string. - // If it does, it then internally records the version as being the latest one that it understands. - // It needs to do this since frame lookup is done by version. - if (Boolean.getBoolean("qpid.accept.broker.version")) - { - versionOk = true; - int lastIndex = ProtocolVersionList.pv.length - 1; - major = ProtocolVersionList.pv[lastIndex][ProtocolVersionList.PROTOCOL_MAJOR]; - minor = ProtocolVersionList.pv[lastIndex][ProtocolVersionList.PROTOCOL_MINOR]; - } - else - { - versionOk = checkVersionOK(major, minor); - } - - if (versionOk) - { - protocolSession.setProtocolVersion(major, minor); - - try - { - // Used to hold the SASL mechanism to authenticate with. - String mechanism; - - if (body.mechanisms == null) - { - throw new AMQException("mechanism not specified in ConnectionStart method frame"); - } - else - { - mechanism = chooseMechanism(body.mechanisms); - _log.debug("mechanism = " + mechanism); - } - - if (mechanism == null) - { - throw new AMQException("No supported security mechanism found, passed: " + new String(body.mechanisms)); - } - - byte[] saslResponse; - try - { - SaslClient sc = - Sasl.createSaslClient(new String[] { mechanism }, null, "AMQP", "localhost", null, - createCallbackHandler(mechanism, protocolSession)); - if (sc == null) - { - throw new AMQException( - "Client SASL configuration error: no SaslClient could be created for mechanism " + mechanism - + ". Please ensure all factories are registered. See DynamicSaslRegistrar for " - + " details of how to register non-standard SASL client providers."); - } - - protocolSession.setSaslClient(sc); - saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); - } - catch (SaslException e) - { - protocolSession.setSaslClient(null); - throw new AMQException("Unable to create SASL client: " + e, e); - } - - if (body.locales == null) - { - throw new AMQException("Locales is not defined in Connection Start method"); - } - - final String locales = new String(body.locales, "utf8"); - final StringTokenizer tokenizer = new StringTokenizer(locales, " "); - String selectedLocale = null; - if (tokenizer.hasMoreTokens()) - { - selectedLocale = tokenizer.nextToken(); - } - else - { - throw new AMQException("No locales sent from server, passed: " + locales); - } - - stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); - FieldTable clientProperties = FieldTableFactory.newFieldTable(); - - clientProperties.setString(new AMQShortString(ClientProperties.instance.toString()), - protocolSession.getClientID()); - clientProperties.setString(new AMQShortString(ClientProperties.product.toString()), - QpidProperties.getProductName()); - clientProperties.setString(new AMQShortString(ClientProperties.version.toString()), - QpidProperties.getReleaseVersion()); - clientProperties.setString(new AMQShortString(ClientProperties.platform.toString()), getFullSystemInfo()); - - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - protocolSession.writeFrame(ConnectionStartOkBody.createAMQFrame(evt.getChannelId(), - protocolSession.getProtocolMajorVersion(), - protocolSession.getProtocolMinorVersion(), - clientProperties, // clientProperties - new AMQShortString(selectedLocale), // locale - new AMQShortString(mechanism), // mechanism - saslResponse)); // response - - } - catch (UnsupportedEncodingException e) - { - throw new AMQException(_log, "Unable to decode data: " + e, e); - } - } - else - { - _log.error("Broker requested Protocol [" + body.versionMajor + "-" + body.versionMinor - + "] which is not supported by this version of the client library"); - - protocolSession.closeProtocolSession(); - } - } - - private boolean checkVersionOK(byte versionMajor, byte versionMinor) - { - byte[][] supportedVersions = ProtocolVersionList.pv; - boolean supported = false; - int i = supportedVersions.length; - while ((i-- != 0) && !supported) - { - supported = (supportedVersions[i][ProtocolVersionList.PROTOCOL_MAJOR] == versionMajor) - && (supportedVersions[i][ProtocolVersionList.PROTOCOL_MINOR] == versionMinor); - } - - return supported; - } - - private String getFullSystemInfo() - { - StringBuffer fullSystemInfo = new StringBuffer(); - fullSystemInfo.append(System.getProperty("java.runtime.name")); - fullSystemInfo.append(", " + System.getProperty("java.runtime.version")); - fullSystemInfo.append(", " + System.getProperty("java.vendor")); - fullSystemInfo.append(", " + System.getProperty("os.arch")); - fullSystemInfo.append(", " + System.getProperty("os.name")); - fullSystemInfo.append(", " + System.getProperty("os.version")); - fullSystemInfo.append(", " + System.getProperty("sun.os.patch.level")); - - return fullSystemInfo.toString(); - } - - private String chooseMechanism(byte[] availableMechanisms) throws UnsupportedEncodingException - { - final String mechanisms = new String(availableMechanisms, "utf8"); - StringTokenizer tokenizer = new StringTokenizer(mechanisms, " "); - HashSet mechanismSet = new HashSet(); - while (tokenizer.hasMoreTokens()) - { - mechanismSet.add(tokenizer.nextToken()); - } - - String preferredMechanisms = CallbackHandlerRegistry.getInstance().getMechanisms(); - StringTokenizer prefTokenizer = new StringTokenizer(preferredMechanisms, " "); - while (prefTokenizer.hasMoreTokens()) - { - String mech = prefTokenizer.nextToken(); - if (mechanismSet.contains(mech)) - { - return mech; - } - } - - return null; - } - - private AMQCallbackHandler createCallbackHandler(String mechanism, AMQProtocolSession protocolSession) - throws AMQException - { - Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism); - try - { - Object instance = mechanismClass.newInstance(); - AMQCallbackHandler cbh = (AMQCallbackHandler) instance; - cbh.initialise(protocolSession); - - return cbh; - } - catch (Exception e) - { - throw new AMQException("Unable to create callback handler: " + e, e); - } - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java deleted file mode 100644 index 67f1a6519f..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java +++ /dev/null @@ -1,97 +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.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.ConnectionTuneParameters; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionOpenBody; -import org.apache.qpid.framing.ConnectionTuneBody; -import org.apache.qpid.framing.ConnectionTuneOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -public class ConnectionTuneMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ConnectionTuneMethodHandler.class); - - private static final ConnectionTuneMethodHandler _instance = new ConnectionTuneMethodHandler(); - - public static ConnectionTuneMethodHandler getInstance() - { - return _instance; - } - - protected ConnectionTuneMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - _logger.debug("ConnectionTune frame received"); - ConnectionTuneBody frame = (ConnectionTuneBody) evt.getMethod(); - - ConnectionTuneParameters params = protocolSession.getConnectionTuneParameters(); - if (params == null) - { - params = new ConnectionTuneParameters(); - } - - params.setFrameMax(frame.frameMax); - params.setChannelMax(frame.channelMax); - params.setHeartbeat(Integer.getInteger("amqj.heartbeat.delay", frame.heartbeat)); - protocolSession.setConnectionTuneParameters(params); - - stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); - protocolSession.writeFrame(createTuneOkFrame(evt.getChannelId(), params,frame.getMajor(), frame.getMinor())); - - String host = protocolSession.getAMQConnection().getVirtualHost(); - AMQShortString virtualHost = new AMQShortString("/" + host); - - - protocolSession.writeFrame(createConnectionOpenFrame(evt.getChannelId(), virtualHost, null, true,frame.getMajor(), frame.getMinor())); - } - - protected AMQFrame createConnectionOpenFrame(int channel, AMQShortString path, AMQShortString capabilities, boolean insist, byte major, byte minor) - { - // Be aware of possible changes to parameter order as versions change. - return ConnectionOpenBody.createAMQFrame(channel, - major, minor, // AMQP version (major, minor) - capabilities, // capabilities - insist, // insist - path); // virtualHost - } - - protected AMQFrame createTuneOkFrame(int channel, ConnectionTuneParameters params, byte major, byte minor) - { - // Be aware of possible changes to parameter order as versions change. - return ConnectionTuneOkBody.createAMQFrame(channel, - major, minor, - params.getChannelMax(), // channelMax - params.getFrameMax(), // frameMax - params.getHeartbeat()); // heartbeat - } -} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java deleted file mode 100644 index 146c705c00..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/ExchangeBoundOkMethodHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * Copyright (c) 2006 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.ExchangeBoundOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -/** - * @author Apache Software Foundation - */ -public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(ExchangeBoundOkMethodHandler.class); - private static final ExchangeBoundOkMethodHandler _instance = new ExchangeBoundOkMethodHandler(); - - public static ExchangeBoundOkMethodHandler getInstance() - { - return _instance; - } - - private ExchangeBoundOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - if (_logger.isDebugEnabled()) - { - ExchangeBoundOkBody body = (ExchangeBoundOkBody) evt.getMethod(); - _logger.debug("Received Exchange.Bound-Ok message, response code: " + body.replyCode + " text: " + - body.replyText); - } - } -} - - diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java deleted file mode 100644 index eaf4721445..0000000000 --- a/java/client/src/main/java/org/apache/qpid/client/handler/QueueDeleteOkMethodHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * Copyright (c) 2006 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.qpid.client.handler; - -import org.apache.log4j.Logger; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.StateAwareMethodListener; -import org.apache.qpid.framing.QueueDeleteOkBody; -import org.apache.qpid.protocol.AMQMethodEvent; - -/** - * @author Apache Software Foundation - */ -public class QueueDeleteOkMethodHandler implements StateAwareMethodListener -{ - private static final Logger _logger = Logger.getLogger(QueueDeleteOkMethodHandler.class); - private static final QueueDeleteOkMethodHandler _instance = new QueueDeleteOkMethodHandler(); - - public static QueueDeleteOkMethodHandler getInstance() - { - return _instance; - } - - private QueueDeleteOkMethodHandler() - { - } - - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException - { - if (_logger.isDebugEnabled()) - { - QueueDeleteOkBody body = (QueueDeleteOkBody) evt.getMethod(); - _logger.debug("Received Queue.Delete-Ok message, message count: " + body.messageCount); - } - } -} - - diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ChannelCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ChannelCloseMethodHandler.java new file mode 100644 index 0000000000..994e58ed03 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ChannelCloseMethodHandler.java @@ -0,0 +1,24 @@ +package org.apache.qpid.client.handler.amqp_0_9; + +import org.apache.qpid.framing.ChannelCloseOkBody; +import org.apache.qpid.framing.amqp_0_9.ChannelCloseOkBodyImpl; + +import org.apache.log4j.Logger; + +public class ChannelCloseMethodHandler extends org.apache.qpid.client.handler.amqp_8_0.ChannelCloseMethodHandler +{ + private static final Logger _logger = Logger.getLogger(ChannelCloseMethodHandler.class); + + private static ChannelCloseMethodHandler _handler = new ChannelCloseMethodHandler(); + + public static ChannelCloseMethodHandler getInstance() + { + return _handler; + } + + + protected ChannelCloseOkBody createChannelCloseOkBody() + { + return new ChannelCloseOkBodyImpl(); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionCloseMethodHandler.java new file mode 100644 index 0000000000..b9b7074fd2 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionCloseMethodHandler.java @@ -0,0 +1,29 @@ +package org.apache.qpid.client.handler.amqp_0_9; + +import org.apache.qpid.framing.ConnectionCloseOkBody; +import org.apache.qpid.framing.amqp_0_9.ConnectionCloseOkBodyImpl; + +import org.apache.log4j.Logger; + +public class ConnectionCloseMethodHandler extends org.apache.qpid.client.handler.amqp_8_0.ConnectionCloseMethodHandler +{ + private static final Logger _logger = Logger.getLogger(ConnectionCloseMethodHandler.class); + + private static ConnectionCloseMethodHandler _handler = new ConnectionCloseMethodHandler(); + + public static ConnectionCloseMethodHandler getInstance() + { + return _handler; + } + + protected ConnectionCloseMethodHandler() + { + } + + + protected ConnectionCloseOkBody createConnectionCloseOkBody() + { + return new ConnectionCloseOkBodyImpl(); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionSecureMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionSecureMethodHandler.java new file mode 100644 index 0000000000..859fd2b63b --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionSecureMethodHandler.java @@ -0,0 +1,28 @@ +package org.apache.qpid.client.handler.amqp_0_9; + +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.ConnectionSecureBody; +import org.apache.qpid.framing.ConnectionSecureOkBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionSecureOkBodyImpl; + +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; + +public class ConnectionSecureMethodHandler extends org.apache.qpid.client.handler.amqp_8_0.ConnectionSecureMethodHandler +{ + private static final ConnectionSecureMethodHandler _instance = new ConnectionSecureMethodHandler(); + + public static ConnectionSecureMethodHandler getInstance() + { + return _instance; + } + + protected ConnectionSecureOkBody createConnectionSecureOkBody(byte[] response) + { + return new ConnectionSecureOkBodyImpl(response); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionTuneMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionTuneMethodHandler.java new file mode 100644 index 0000000000..e28619b378 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_0_9/ConnectionTuneMethodHandler.java @@ -0,0 +1,41 @@ +package org.apache.qpid.client.handler.amqp_0_9; + +import org.apache.qpid.client.ConnectionTuneParameters; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ConnectionOpenBody; +import org.apache.qpid.framing.ConnectionTuneOkBody; +import org.apache.qpid.framing.amqp_0_9.ConnectionOpenBodyImpl; +import org.apache.qpid.framing.amqp_0_9.ConnectionTuneOkBodyImpl; + +import org.apache.log4j.Logger; + +public class ConnectionTuneMethodHandler extends org.apache.qpid.client.handler.amqp_8_0.ConnectionTuneMethodHandler +{ + private static final Logger _logger = Logger.getLogger(ConnectionTuneMethodHandler.class); + + private static final ConnectionTuneMethodHandler _instance = new ConnectionTuneMethodHandler(); + + public static ConnectionTuneMethodHandler getInstance() + { + return _instance; + } + + + protected ConnectionOpenBody createConnectionOpenBody(AMQShortString path, AMQShortString capabilities, boolean insist) + { + + return new ConnectionOpenBodyImpl(path,// virtualHost + capabilities, // capabilities + insist); // insist + + } + + protected ConnectionTuneOkBody createTuneOkBody(ConnectionTuneParameters params) + { + // Be aware of possible changes to parameter order as versions change. + return new ConnectionTuneOkBodyImpl( + params.getChannelMax(), // channelMax + params.getFrameMax(), // frameMax + params.getHeartbeat()); // heartbeat + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicCancelOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicCancelOkMethodHandler.java new file mode 100644 index 0000000000..2acf3005f1 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicCancelOkMethodHandler.java @@ -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. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.BasicCancelOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +/** + * @author Apache Software Foundation + */ +public class BasicCancelOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(BasicCancelOkMethodHandler.class); + private static final BasicCancelOkMethodHandler _instance = new BasicCancelOkMethodHandler(); + + public static BasicCancelOkMethodHandler getInstance() + { + return _instance; + } + + private BasicCancelOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + + _logger.debug("New BasicCancelOk method received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + BasicCancelOkBody body = (BasicCancelOkBody) evt.getMethod(); + protocolSession.confirmConsumerCancelled(evt.getChannelId(), body.getConsumerTag()); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicDeliverMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicDeliverMethodHandler.java new file mode 100644 index 0000000000..47586db2f2 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicDeliverMethodHandler.java @@ -0,0 +1,50 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.message.UnprocessedMessage; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.BasicDeliverBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class BasicDeliverMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(BasicDeliverMethodHandler.class); + + private static final BasicDeliverMethodHandler _instance = new BasicDeliverMethodHandler(); + + public static BasicDeliverMethodHandler getInstance() + { + return _instance; + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(), (BasicDeliverBody) evt.getMethod()); + _logger.debug("New JmsDeliver method received"); + protocolSession.unprocessedMessageReceived(msg); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicReturnMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicReturnMethodHandler.java new file mode 100644 index 0000000000..ad5a1331b0 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/BasicReturnMethodHandler.java @@ -0,0 +1,51 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.message.UnprocessedMessage; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.BasicReturnBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class BasicReturnMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(BasicReturnMethodHandler.class); + + private static final BasicReturnMethodHandler _instance = new BasicReturnMethodHandler(); + + public static BasicReturnMethodHandler getInstance() + { + return _instance; + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + _logger.debug("New JmsBounce method received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + final UnprocessedMessage msg = new UnprocessedMessage(evt.getChannelId(),(BasicReturnBody)evt.getMethod()); + + protocolSession.unprocessedMessageReceived(msg); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseMethodHandler.java new file mode 100644 index 0000000000..edfd8e5110 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseMethodHandler.java @@ -0,0 +1,106 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQChannelClosedException; +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQInvalidRoutingKeyException; +import org.apache.qpid.client.AMQNoConsumersException; +import org.apache.qpid.client.AMQNoRouteException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ChannelCloseBody; +import org.apache.qpid.framing.ChannelCloseOkBody; +import org.apache.qpid.framing.amqp_8_0.ChannelCloseOkBodyImpl; +import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ChannelCloseMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ChannelCloseMethodHandler.class); + + private static ChannelCloseMethodHandler _handler = new ChannelCloseMethodHandler(); + + public static ChannelCloseMethodHandler getInstance() + { + return _handler; + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + _logger.debug("ChannelClose method received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); + + AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); + AMQShortString reason = method.getReplyText(); + if (_logger.isDebugEnabled()) + { + _logger.debug("Channel close reply code: " + errorCode + ", reason: " + reason); + } + + protocolSession.getOutputHandler().sendCommand(evt.getChannelId(), createChannelCloseOkBody()); + + + + if (errorCode != AMQConstant.REPLY_SUCCESS) + { + if (_logger.isDebugEnabled()) + { + _logger.debug("Channel close received with errorCode " + errorCode + ", and reason " + reason); + } + if (errorCode == AMQConstant.NO_CONSUMERS) + { + throw new AMQNoConsumersException("Error: " + reason, null); + } + else if (errorCode == AMQConstant.NO_ROUTE) + { + throw new AMQNoRouteException("Error: " + reason, null); + } + else if (errorCode == AMQConstant.INVALID_ARGUMENT) + { + _logger.debug("Broker responded with Invalid Argument."); + + throw new org.apache.qpid.AMQInvalidArgumentException(String.valueOf(reason)); + } + else if (errorCode == AMQConstant.INVALID_ROUTING_KEY) + { + _logger.debug("Broker responded with Invalid Routing Key."); + + throw new AMQInvalidRoutingKeyException(String.valueOf(reason)); + } + else + { + throw new AMQChannelClosedException(errorCode, "Error: " + reason); + } + + } + protocolSession.channelClosed(evt.getChannelId(), errorCode, String.valueOf(reason)); + } + + protected ChannelCloseOkBody createChannelCloseOkBody() + { + return new ChannelCloseOkBodyImpl(); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseOkMethodHandler.java new file mode 100644 index 0000000000..d51f1d9c41 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelCloseOkMethodHandler.java @@ -0,0 +1,46 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ChannelCloseOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ChannelCloseOkMethodHandler.class); + + private static final ChannelCloseOkMethodHandler _instance = new ChannelCloseOkMethodHandler(); + + public static ChannelCloseOkMethodHandler getInstance() + { + return _instance; + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + _logger.info("Received channel-close-ok for channel-id " + evt.getChannelId()); + + //todo this should do the closure + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelFlowOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelFlowOkMethodHandler.java new file mode 100644 index 0000000000..baa9cb4319 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ChannelFlowOkMethodHandler.java @@ -0,0 +1,49 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.ChannelFlowOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ChannelFlowOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ChannelFlowOkMethodHandler.class); + private static final ChannelFlowOkMethodHandler _instance = new ChannelFlowOkMethodHandler(); + + public static ChannelFlowOkMethodHandler getInstance() + { + return _instance; + } + + private ChannelFlowOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + ChannelFlowOkBody method = (ChannelFlowOkBody) evt.getMethod(); + _logger.debug("Received Channel.Flow-Ok message, active = " + method.getActive()); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionCloseMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionCloseMethodHandler.java new file mode 100644 index 0000000000..57eaaff531 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionCloseMethodHandler.java @@ -0,0 +1,112 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQConnectionClosedException; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.AMQAuthenticationException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.ConnectionCloseOkBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionCloseOkBodyImpl; +import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ConnectionCloseMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ConnectionCloseMethodHandler.class); + + private static ConnectionCloseMethodHandler _handler = new ConnectionCloseMethodHandler(); + + public static ConnectionCloseMethodHandler getInstance() + { + return _handler; + } + + protected ConnectionCloseMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + _logger.info("ConnectionClose frame received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + ConnectionCloseBody method = (ConnectionCloseBody) evt.getMethod(); + + // does it matter + //stateManager.changeState(AMQState.CONNECTION_CLOSING); + + AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); + AMQShortString reason = method.getReplyText(); + + try + { + + + + ConnectionCloseOkBody closeOkBody = createConnectionCloseOkBody(); + protocolSession.getOutputHandler().sendCommand(0, closeOkBody); + + + + if (errorCode != AMQConstant.REPLY_SUCCESS) + { + if (errorCode == AMQConstant.NOT_ALLOWED) + { + _logger.info("Authentication Error:" + Thread.currentThread().getName()); + + protocolSession.closeProtocolSession(); + + //todo this is a bit of a fudge (could be conssidered such as each new connection needs a new state manager or at least a fresh state. + stateManager.changeState(AMQState.CONNECTION_NOT_STARTED); + + throw new AMQAuthenticationException(errorCode, reason == null ? null : reason.toString()); + } + else + { + _logger.info("Connection close received with error code " + errorCode); + + + throw new AMQConnectionClosedException(errorCode, "Error: " + reason); + } + } + } + finally + { + // this actually closes the connection in the case where it is not an error. + + protocolSession.closeProtocolSession(); + + stateManager.changeState(AMQState.CONNECTION_CLOSED); + } + } + + protected ConnectionCloseOkBody createConnectionCloseOkBody() + { + return new ConnectionCloseOkBodyImpl(); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionOpenOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionOpenOkMethodHandler.java new file mode 100644 index 0000000000..f4327ac748 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionOpenOkMethodHandler.java @@ -0,0 +1,47 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.qpid.AMQException; +import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ConnectionOpenOkMethodHandler implements StateAwareMethodListener +{ + private static final ConnectionOpenOkMethodHandler _instance = new ConnectionOpenOkMethodHandler(); + + public static ConnectionOpenOkMethodHandler getInstance() + { + return _instance; + } + + private ConnectionOpenOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + stateManager.changeState(AMQState.CONNECTION_OPEN); + } + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionRedirectMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionRedirectMethodHandler.java new file mode 100644 index 0000000000..8291b62596 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionRedirectMethodHandler.java @@ -0,0 +1,71 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.ConnectionRedirectBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ConnectionRedirectMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ConnectionRedirectMethodHandler.class); + + private static final int DEFAULT_REDIRECT_PORT = 5672; + + private static ConnectionRedirectMethodHandler _handler = new ConnectionRedirectMethodHandler(); + + public static ConnectionRedirectMethodHandler getInstance() + { + return _handler; + } + + private ConnectionRedirectMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + _logger.info("ConnectionRedirect frame received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + ConnectionRedirectBody method = (ConnectionRedirectBody) evt.getMethod(); + + String host = method.getHost().toString(); + // the host is in the form hostname:port with the port being optional + int portIndex = host.indexOf(':'); + + int port; + if (portIndex == -1) + { + port = DEFAULT_REDIRECT_PORT; + } + else + { + port = Integer.parseInt(host.substring(portIndex + 1)); + host = host.substring(0, portIndex); + + } + protocolSession.failover(host, port); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionSecureMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionSecureMethodHandler.java new file mode 100644 index 0000000000..f5d1840f45 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionSecureMethodHandler.java @@ -0,0 +1,75 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; + +import org.apache.qpid.AMQException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.ConnectionSecureBody; +import org.apache.qpid.framing.ConnectionSecureOkBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionSecureOkBodyImpl; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ConnectionSecureMethodHandler implements StateAwareMethodListener +{ + private static final ConnectionSecureMethodHandler _instance = new ConnectionSecureMethodHandler(); + + public static ConnectionSecureMethodHandler getInstance() + { + return _instance; + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + SaslClient client = protocolSession.getSaslClient(); + if (client == null) + { + throw new AMQException("No SASL client set up - cannot proceed with authentication"); + } + + ConnectionSecureBody body = (ConnectionSecureBody) evt.getMethod(); + + try + { + // Evaluate server challenge + byte[] response = client.evaluateChallenge(body.getChallenge()); + + ConnectionSecureOkBody secureOkBody = createConnectionSecureOkBody(response); + protocolSession.getOutputHandler().sendCommand(evt.getChannelId(),secureOkBody); + } + catch (SaslException e) + { + throw new AMQException("Error processing SASL challenge: " + e, e); + } + + + } + + protected ConnectionSecureOkBody createConnectionSecureOkBody(byte[] response) + { + return new ConnectionSecureOkBodyImpl(response); + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionStartMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionStartMethodHandler.java new file mode 100644 index 0000000000..10473b9751 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionStartMethodHandler.java @@ -0,0 +1,243 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import java.io.UnsupportedEncodingException; +import java.util.HashSet; +import java.util.StringTokenizer; + +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; + +import org.apache.log4j.Logger; + +import org.apache.qpid.AMQException; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.security.AMQCallbackHandler; +import org.apache.qpid.client.security.CallbackHandlerRegistry; +import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.common.ClientProperties; +import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ConnectionStartBody; +import org.apache.qpid.framing.ConnectionStartOkBody; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.FieldTableFactory; +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.framing.amqp_8_0.ConnectionStartOkBodyImpl; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ConnectionStartMethodHandler implements StateAwareMethodListener +{ + private static final Logger _log = Logger.getLogger(ConnectionStartMethodHandler.class); + + private static final ConnectionStartMethodHandler _instance = new ConnectionStartMethodHandler(); + + public static ConnectionStartMethodHandler getInstance() + { + return _instance; + } + + private ConnectionStartMethodHandler() + { } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) + throws AMQException + { + _log.debug("public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, " + + "AMQMethodEvent evt): called"); + + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + ConnectionStartBody body = (ConnectionStartBody) evt.getMethod(); + + ProtocolVersion pv = new ProtocolVersion((byte) body.getVersionMajor(),(byte) body.getVersionMinor()); + + + // For the purposes of interop, we can make the client accept the broker's version string. + // If it does, it then internally records the version as being the latest one that it understands. + // It needs to do this since frame lookup is done by version. + if (Boolean.getBoolean("qpid.accept.broker.version") && !pv.isSupported()) + { + + pv = ProtocolVersion.getLatestSupportedVersion(); + } + + if (pv.isSupported()) + { + protocolSession.setProtocolVersion(pv); + + try + { + // Used to hold the SASL mechanism to authenticate with. + String mechanism; + + if (body.getMechanisms() == null) + { + throw new AMQException("mechanism not specified in ConnectionStart method frame"); + } + else + { + mechanism = chooseMechanism(body.getMechanisms()); + _log.debug("mechanism = " + mechanism); + } + + if (mechanism == null) + { + throw new AMQException("No supported security mechanism found, passed: " + new String(body.getMechanisms())); + } + + byte[] saslResponse; + try + { + SaslClient sc = + Sasl.createSaslClient(new String[] { mechanism }, null, "AMQP", "localhost", null, + createCallbackHandler(mechanism, protocolSession)); + if (sc == null) + { + throw new AMQException( + "Client SASL configuration error: no SaslClient could be created for mechanism " + mechanism + + ". Please ensure all factories are registered. See DynamicSaslRegistrar for " + + " details of how to register non-standard SASL client providers."); + } + + protocolSession.setSaslClient(sc); + saslResponse = (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[0]) : null); + } + catch (SaslException e) + { + protocolSession.setSaslClient(null); + throw new AMQException("Unable to create SASL client: " + e, e); + } + + if (body.getLocales() == null) + { + throw new AMQException("Locales is not defined in Connection Start method"); + } + + final String locales = new String(body.getLocales(), "utf8"); + final StringTokenizer tokenizer = new StringTokenizer(locales, " "); + String selectedLocale = null; + if (tokenizer.hasMoreTokens()) + { + selectedLocale = tokenizer.nextToken(); + } + else + { + throw new AMQException("No locales sent from server, passed: " + locales); + } + + stateManager.changeState(AMQState.CONNECTION_NOT_TUNED); + FieldTable clientProperties = FieldTableFactory.newFieldTable(); + + clientProperties.setString(ClientProperties.instance.getName(), + protocolSession.getClientID()); + clientProperties.setString(ClientProperties.product.getName(), + QpidProperties.getProductName()); + clientProperties.setString(ClientProperties.version.getName(), + QpidProperties.getReleaseVersion()); + clientProperties.setString(ClientProperties.platform.getName(), getFullSystemInfo()); + + ConnectionStartOkBody startOkBody = createConnectionStartOkBody(clientProperties, // clientProperties + new AMQShortString(selectedLocale), // locale + new AMQShortString(mechanism), // mechanism + saslResponse); // response + protocolSession.getOutputHandler().sendCommand(0, startOkBody); + + } + catch (UnsupportedEncodingException e) + { + throw new AMQException(_log, "Unable to decode data: " + e, e); + } + } + else + { + _log.error("Broker requested Protocol [" + body.getVersionMajor() + "-" + body.getVersionMinor() + + "] which is not supported by this version of the client library"); + + protocolSession.closeProtocolSession(); + } + } + + private ConnectionStartOkBody createConnectionStartOkBody(FieldTable clientProperties, AMQShortString locale, AMQShortString mechanism, byte[] saslResponse) + { + return new ConnectionStartOkBodyImpl(clientProperties,mechanism,saslResponse,locale); + } + + + private String getFullSystemInfo() + { + StringBuffer fullSystemInfo = new StringBuffer(); + fullSystemInfo.append(System.getProperty("java.runtime.name")); + fullSystemInfo.append(", " + System.getProperty("java.runtime.version")); + fullSystemInfo.append(", " + System.getProperty("java.vendor")); + fullSystemInfo.append(", " + System.getProperty("os.arch")); + fullSystemInfo.append(", " + System.getProperty("os.name")); + fullSystemInfo.append(", " + System.getProperty("os.version")); + fullSystemInfo.append(", " + System.getProperty("sun.os.patch.level")); + + return fullSystemInfo.toString(); + } + + private String chooseMechanism(byte[] availableMechanisms) throws UnsupportedEncodingException + { + final String mechanisms = new String(availableMechanisms, "utf8"); + StringTokenizer tokenizer = new StringTokenizer(mechanisms, " "); + HashSet mechanismSet = new HashSet(); + while (tokenizer.hasMoreTokens()) + { + mechanismSet.add(tokenizer.nextToken()); + } + + String preferredMechanisms = CallbackHandlerRegistry.getInstance().getMechanisms(); + StringTokenizer prefTokenizer = new StringTokenizer(preferredMechanisms, " "); + while (prefTokenizer.hasMoreTokens()) + { + String mech = prefTokenizer.nextToken(); + if (mechanismSet.contains(mech)) + { + return mech; + } + } + + return null; + } + + private AMQCallbackHandler createCallbackHandler(String mechanism, AMQProtocolSession protocolSession) + throws AMQException + { + Class mechanismClass = CallbackHandlerRegistry.getInstance().getCallbackHandlerClass(mechanism); + try + { + Object instance = mechanismClass.newInstance(); + AMQCallbackHandler cbh = (AMQCallbackHandler) instance; + cbh.initialise(protocolSession); + + return cbh; + } + catch (Exception e) + { + throw new AMQException("Unable to create callback handler: " + e, e); + } + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionTuneMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionTuneMethodHandler.java new file mode 100644 index 0000000000..3eb3401e37 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ConnectionTuneMethodHandler.java @@ -0,0 +1,99 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.ConnectionTuneParameters; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.ConnectionOpenBody; +import org.apache.qpid.framing.ConnectionTuneBody; +import org.apache.qpid.framing.ConnectionTuneOkBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionOpenBodyImpl; +import org.apache.qpid.framing.amqp_8_0.ConnectionTuneOkBodyImpl; +import org.apache.qpid.protocol.AMQMethodEvent; + +public class ConnectionTuneMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ConnectionTuneMethodHandler.class); + + private static final ConnectionTuneMethodHandler _instance = new ConnectionTuneMethodHandler(); + + public static ConnectionTuneMethodHandler getInstance() + { + return _instance; + } + + protected ConnectionTuneMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + _logger.debug("ConnectionTune frame received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); + ConnectionTuneBody frame = (ConnectionTuneBody) evt.getMethod(); + + ConnectionTuneParameters params = protocolSession.getConnectionTuneParameters(); + if (params == null) + { + params = new ConnectionTuneParameters(); + } + + params.setFrameMax(frame.getFrameMax()); + params.setChannelMax(frame.getChannelMax()); + params.setHeartbeat(Integer.getInteger("amqj.heartbeat.delay", frame.getHeartbeat())); + protocolSession.setConnectionTuneParameters(params); + + stateManager.changeState(AMQState.CONNECTION_NOT_OPENED); + protocolSession.getOutputHandler().sendCommand(evt.getChannelId(), + createTuneOkBody(params)); + + String host = protocolSession.getAMQConnection().getVirtualHost(); + AMQShortString virtualHost = new AMQShortString("/" + host); + + + protocolSession.getOutputHandler().sendCommand(evt.getChannelId(), + createConnectionOpenBody( virtualHost, null, true)); + } + + protected ConnectionOpenBody createConnectionOpenBody(AMQShortString path, AMQShortString capabilities, boolean insist) + { + + return new ConnectionOpenBodyImpl(path,// virtualHost + capabilities, // capabilities + insist); // insist + + } + + protected ConnectionTuneOkBody createTuneOkBody(ConnectionTuneParameters params) + { + // Be aware of possible changes to parameter order as versions change. + return new ConnectionTuneOkBodyImpl( + params.getChannelMax(), // channelMax + params.getFrameMax(), // frameMax + params.getHeartbeat()); // heartbeat + } +} diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ExchangeBoundOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ExchangeBoundOkMethodHandler.java new file mode 100644 index 0000000000..0752b38aaf --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/ExchangeBoundOkMethodHandler.java @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.ExchangeBoundOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +/** + * @author Apache Software Foundation + */ +public class ExchangeBoundOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(ExchangeBoundOkMethodHandler.class); + private static final ExchangeBoundOkMethodHandler _instance = new ExchangeBoundOkMethodHandler(); + + public static ExchangeBoundOkMethodHandler getInstance() + { + return _instance; + } + + private ExchangeBoundOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + if (_logger.isDebugEnabled()) + { + ExchangeBoundOkBody body = (ExchangeBoundOkBody) evt.getMethod(); + _logger.debug("Received Exchange.Bound-Ok message, response code: " + body.getReplyCode() + " text: " + + body.getReplyText()); + } + } +} + + diff --git a/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/QueueDeleteOkMethodHandler.java b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/QueueDeleteOkMethodHandler.java new file mode 100644 index 0000000000..50bf03fe76 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/handler/amqp_8_0/QueueDeleteOkMethodHandler.java @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.qpid.client.handler.amqp_8_0; + +import org.apache.log4j.Logger; +import org.apache.qpid.AMQException; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.StateAwareMethodListener; +import org.apache.qpid.framing.QueueDeleteOkBody; +import org.apache.qpid.protocol.AMQMethodEvent; + +/** + * @author Apache Software Foundation + */ +public class QueueDeleteOkMethodHandler implements StateAwareMethodListener +{ + private static final Logger _logger = Logger.getLogger(QueueDeleteOkMethodHandler.class); + private static final QueueDeleteOkMethodHandler _instance = new QueueDeleteOkMethodHandler(); + + public static QueueDeleteOkMethodHandler getInstance() + { + return _instance; + } + + private QueueDeleteOkMethodHandler() + { + } + + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException + { + if (_logger.isDebugEnabled()) + { + QueueDeleteOkBody body = (QueueDeleteOkBody) evt.getMethod(); + _logger.debug("Received Queue.Delete-Ok message, message count: " + body.getMessageCount()); + } + } +} + + diff --git a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java index 36dd4d400c..66524edce3 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/AbstractJMSMessage.java @@ -121,12 +121,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public String getJMSMessageID() throws JMSException { - if (getContentHeaderProperties().getMessageId() == null) + if (getContentHeaderProperties().getMessageIdAsString() == null) { getContentHeaderProperties().setMessageId("ID:" + _deliveryTag); } - return getContentHeaderProperties().getMessageId(); + return getContentHeaderProperties().getMessageIdAsString(); } public void setJMSMessageID(String messageId) throws JMSException @@ -146,7 +146,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public byte[] getJMSCorrelationIDAsBytes() throws JMSException { - return getContentHeaderProperties().getCorrelationId().getBytes(); + return getContentHeaderProperties().getCorrelationIdAsString().getBytes(); } public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException @@ -161,12 +161,12 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public String getJMSCorrelationID() throws JMSException { - return getContentHeaderProperties().getCorrelationId(); + return getContentHeaderProperties().getCorrelationIdAsString(); } public Destination getJMSReplyTo() throws JMSException { - String replyToEncoding = getContentHeaderProperties().getReplyTo(); + String replyToEncoding = getContentHeaderProperties().getReplyToAsString(); if (replyToEncoding == null) { return null; @@ -250,7 +250,7 @@ public abstract class AbstractJMSMessage extends AMQMessage implements org.apach public String getJMSType() throws JMSException { - return getContentHeaderProperties().getType(); + return getContentHeaderProperties().getTypeAsString(); } public void setJMSType(String string) throws JMSException diff --git a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java index c05667902f..763af312f4 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/JMSTextMessage.java @@ -116,7 +116,7 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text _data.limit(text.length()) ; //_data.sweep(); _data.setAutoExpand(true); - final String encoding = getContentHeaderProperties().getEncoding(); + final String encoding = getContentHeaderProperties().getEncodingAsString(); if (encoding == null) { _data.put(text.getBytes()); @@ -155,11 +155,11 @@ public class JMSTextMessage extends AbstractJMSMessage implements javax.jms.Text { return null; } - if (getContentHeaderProperties().getEncoding() != null) + if (getContentHeaderProperties().getEncodingAsString() != null) { try { - _decodedValue = _data.getString(Charset.forName(getContentHeaderProperties().getEncoding()).newDecoder()); + _decodedValue = _data.getString(Charset.forName(getContentHeaderProperties().getEncodingAsString()).newDecoder()); } catch (CharacterCodingException e) { diff --git a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java index e02771d8f5..c2015f9e7c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java +++ b/java/client/src/main/java/org/apache/qpid/client/message/MessageFactoryRegistry.java @@ -92,14 +92,14 @@ public class MessageFactoryRegistry // Get the message content type. This may be null for pure AMQP messages, but will always be set for JMS over // AMQP. When the type is null, it can only be assumed that the message is a byte message. - AMQShortString contentTypeShortString = properties.getContentTypeShortString(); + AMQShortString contentTypeShortString = properties.getContentType(); contentTypeShortString = (contentTypeShortString == null) ? new AMQShortString(JMSBytesMessage.MIME_TYPE) : contentTypeShortString; MessageFactory mf = _mimeShortStringToFactoryMap.get(contentTypeShortString); if (mf == null) { - throw new AMQException("Unsupport MIME type of " + properties.getContentType()); + throw new AMQException("Unsupport MIME type of " + properties.getContentTypeAsString()); } else { diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java index d0cc52271a..93c0cb5c12 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandler.java @@ -1,630 +1,36 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ package org.apache.qpid.client.protocol; -import java.util.Iterator; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.CountDownLatch; - -import org.apache.log4j.Logger; -import org.apache.mina.common.IdleStatus; -import org.apache.mina.common.IoHandlerAdapter; -import org.apache.mina.common.IoSession; -import org.apache.mina.filter.SSLFilter; -import org.apache.mina.filter.codec.ProtocolCodecFilter; -import org.apache.qpid.AMQConnectionClosedException; -import org.apache.qpid.AMQDisconnectedException; -import org.apache.qpid.AMQException; -import org.apache.qpid.AMQTimeoutException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQSession; -import org.apache.qpid.client.SSLConfiguration; -import org.apache.qpid.client.failover.FailoverHandler; -import org.apache.qpid.client.failover.FailoverState; -import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; -import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.AMQBody; import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionCloseOkBody; -import org.apache.qpid.framing.ContentBody; -import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.HeartbeatBody; -import org.apache.qpid.pool.ReadWriteThreadModel; -import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.protocol.AMQMethodListener; -import org.apache.qpid.ssl.SSLContextFactory; - +import org.apache.qpid.AMQException; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.state.AMQStateManager; -public class AMQProtocolHandler extends IoHandlerAdapter +/** + * Created by IntelliJ IDEA. + * User: U146758 + * Date: 07-Mar-2007 + * Time: 19:40:08 + * To change this template use File | Settings | File Templates. + */ +public interface AMQProtocolHandler { - private static final Logger _logger = Logger.getLogger(AMQProtocolHandler.class); - - /** - * The connection that this protocol handler is associated with. There is a 1-1 mapping between connection instances - * and protocol handler instances. - */ - private AMQConnection _connection; - - /** Our wrapper for a protocol session that provides access to session values in a typesafe manner. */ - private volatile AMQProtocolSession _protocolSession; - - private AMQStateManager _stateManager = new AMQStateManager(); - - private final CopyOnWriteArraySet _frameListeners = new CopyOnWriteArraySet(); - - /** - * We create the failover handler when the session is created since it needs a reference to the IoSession in order - * to be able to send errors during failover back to the client application. The session won't be available in the - * case where we failing over due to a Connection.Redirect message from the broker. - */ - private FailoverHandler _failoverHandler; - - /** - * This flag is used to track whether failover is being attempted. It is used to prevent the application constantly - * attempting failover where it is failing. - */ - private FailoverState _failoverState = FailoverState.NOT_STARTED; - - private CountDownLatch _failoverLatch; - - private final long DEFAULT_SYNC_TIMEOUT = 1000 * 30; - - public AMQProtocolHandler(AMQConnection con) - { - _connection = con; - } - - public void sessionCreated(IoSession session) throws Exception - { - _logger.debug("Protocol session created for session " + System.identityHashCode(session)); - _failoverHandler = new FailoverHandler(this, session); - - final ProtocolCodecFilter pcf = new ProtocolCodecFilter(new AMQCodecFactory(false)); - - if (Boolean.getBoolean("amqj.shared_read_write_pool")) - { - session.getFilterChain().addBefore("AsynchronousWriteFilter", "protocolFilter", pcf); - } - else - { - session.getFilterChain().addLast("protocolFilter", pcf); - } - // we only add the SSL filter where we have an SSL connection - if (_connection.getSSLConfiguration() != null) - { - SSLConfiguration sslConfig = _connection.getSSLConfiguration(); - SSLContextFactory sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType()); - SSLFilter sslFilter = new SSLFilter(sslFactory.buildClientContext()); - sslFilter.setUseClientMode(true); - session.getFilterChain().addBefore("protocolFilter", "ssl", sslFilter); - } - - - try - { - - ReadWriteThreadModel threadModel = ReadWriteThreadModel.getInstance(); - threadModel.getAsynchronousReadFilter().createNewJobForSession(session); - threadModel.getAsynchronousWriteFilter().createNewJobForSession(session); - } - catch (RuntimeException e) - { - e.printStackTrace(); - } - - _protocolSession = new AMQProtocolSession(this, session, _connection, getStateManager()); - _protocolSession.init(); - } - - public void sessionOpened(IoSession session) throws Exception - { - //System.setProperty("foo", "bar"); - } - - /** - * When the broker connection dies we can either get sessionClosed() called or exceptionCaught() followed by - * sessionClosed() depending on whether we were trying to send data at the time of failure. - * - * @param session - * - * @throws Exception - */ - public void sessionClosed(IoSession session) throws Exception - { - if (_connection.isClosed()) - { - _logger.info("Session closed called by client"); - } - else - { - _logger.info("Session closed called with failover state currently " + _failoverState); - - //reconnetablility was introduced here so as not to disturb the client as they have made their intentions - // known through the policy settings. - - if ((_failoverState != FailoverState.IN_PROGRESS) && _connection.failoverAllowed()) - { - _logger.info("FAILOVER STARTING"); - if (_failoverState == FailoverState.NOT_STARTED) - { - _failoverState = FailoverState.IN_PROGRESS; - startFailoverThread(); - } - else - { - _logger.info("Not starting failover as state currently " + _failoverState); - } - } - else - { - _logger.info("Failover not allowed by policy."); - - if (_logger.isDebugEnabled()) - { - _logger.debug(_connection.getFailoverPolicy().toString()); - } - - if (_failoverState != FailoverState.IN_PROGRESS) - { - _logger.info("sessionClose() not allowed to failover"); - _connection.exceptionReceived( - new AMQDisconnectedException("Server closed connection and reconnection " + - "not permitted.")); - } - else - { - _logger.info("sessionClose() failover in progress"); - } - } - } - - _logger.info("Protocol Session [" + this + "] closed"); - } - - /** See {@link FailoverHandler} to see rationale for separate thread. */ - private void startFailoverThread() - { - Thread failoverThread = new Thread(_failoverHandler); - failoverThread.setName("Failover"); - // Do not inherit daemon-ness from current thread as this can be a daemon - // thread such as a AnonymousIoService thread. - failoverThread.setDaemon(false); - failoverThread.start(); - } - - public void sessionIdle(IoSession session, IdleStatus status) throws Exception - { - _logger.debug("Protocol Session [" + this + ":" + session + "] idle: " + status); - if (IdleStatus.WRITER_IDLE.equals(status)) - { - //write heartbeat frame: - _logger.debug("Sent heartbeat"); - session.write(HeartbeatBody.FRAME); - HeartbeatDiagnostics.sent(); - } - else if (IdleStatus.READER_IDLE.equals(status)) - { - //failover: - HeartbeatDiagnostics.timeout(); - _logger.warn("Timed out while waiting for heartbeat from peer."); - session.close(); - } - } - - public void exceptionCaught(IoSession session, Throwable cause) throws Exception - { - if (_failoverState == FailoverState.NOT_STARTED) - { - //if (!(cause instanceof AMQUndeliveredException) && (!(cause instanceof AMQAuthenticationException))) - if (cause instanceof AMQConnectionClosedException) - { - _logger.info("Exception caught therefore going to attempt failover: " + cause, cause); - // this will attemp failover - - sessionClosed(session); - } - } - // we reach this point if failover was attempted and failed therefore we need to let the calling app - // know since we cannot recover the situation - else if (_failoverState == FailoverState.FAILED) - { - _logger.error("Exception caught by protocol handler: " + cause, cause); - // we notify the state manager of the error in case we have any clients waiting on a state - // change. Those "waiters" will be interrupted and can handle the exception - AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); - propagateExceptionToWaiters(amqe); - _connection.exceptionReceived(cause); - } - } - - /** - * There are two cases where we have other threads potentially blocking for events to be handled by this class. - * These are for the state manager (waiting for a state change) or a frame listener (waiting for a particular type - * of frame to arrive). When an error occurs we need to notify these waiters so that they can react appropriately. - * - * @param e the exception to propagate - */ - public void propagateExceptionToWaiters(Exception e) - { - getStateManager().error(e); - if (!_frameListeners.isEmpty()) - { - final Iterator it = _frameListeners.iterator(); - while (it.hasNext()) - { - final AMQMethodListener ml = (AMQMethodListener) it.next(); - ml.error(e); - } - } - } - - private static int _messageReceivedCount; - - public void messageReceived(IoSession session, Object message) throws Exception - { - final boolean debug = _logger.isDebugEnabled(); - final long msgNumber = ++_messageReceivedCount; - - if (debug && (msgNumber % 1000 == 0)) - { - _logger.debug("Received " + _messageReceivedCount + " protocol messages"); - } - - AMQFrame frame = (AMQFrame) message; - - final AMQBody bodyFrame = frame.getBodyFrame(); - - HeartbeatDiagnostics.received(bodyFrame instanceof HeartbeatBody); - - switch (bodyFrame.getFrameType()) - { - case AMQMethodBody.TYPE: - - if (debug) - { - _logger.debug("(" + System.identityHashCode(this) + ")Method frame received: " + frame); - } - - final AMQMethodEvent evt = new AMQMethodEvent(frame.getChannel(), (AMQMethodBody) bodyFrame); - - try - { - - boolean wasAnyoneInterested = getStateManager().methodReceived(evt); - if (!_frameListeners.isEmpty()) - { - Iterator it = _frameListeners.iterator(); - while (it.hasNext()) - { - final AMQMethodListener listener = (AMQMethodListener) it.next(); - wasAnyoneInterested = listener.methodReceived(evt) || wasAnyoneInterested; - } - } - if (!wasAnyoneInterested) - { - throw new AMQException("AMQMethodEvent " + evt + " was not processed by any listener. Listeners:" + _frameListeners); - } - } - catch (AMQException e) - { - getStateManager().error(e); - if (!_frameListeners.isEmpty()) - { - Iterator it = _frameListeners.iterator(); - while (it.hasNext()) - { - final AMQMethodListener listener = (AMQMethodListener) it.next(); - listener.error(e); - } - } - exceptionCaught(session, e); - } - break; - - case ContentHeaderBody.TYPE: - - _protocolSession.messageContentHeaderReceived(frame.getChannel(), - (ContentHeaderBody) bodyFrame); - break; - - case ContentBody.TYPE: - - _protocolSession.messageContentBodyReceived(frame.getChannel(), - (ContentBody) bodyFrame); - break; - - case HeartbeatBody.TYPE: - - if (debug) - { - _logger.debug("Received heartbeat"); - } - break; - - default: - - } - _connection.bytesReceived(_protocolSession.getIoSession().getReadBytes()); - } - - private static int _messagesOut; - - public void messageSent(IoSession session, Object message) throws Exception - { - final long sentMessages = _messagesOut++; - - final boolean debug = _logger.isDebugEnabled(); - - if (debug && (sentMessages % 1000 == 0)) - { - _logger.debug("Sent " + _messagesOut + " protocol messages"); - } - _connection.bytesSent(session.getWrittenBytes()); - if (debug) - { - _logger.debug("Sent frame " + message); - } - } - - /* - public void addFrameListener(AMQMethodListener listener) - { - _frameListeners.add(listener); - } - - public void removeFrameListener(AMQMethodListener listener) - { - _frameListeners.remove(listener); - } - */ - public void attainState(AMQState s) throws AMQException - { - getStateManager().attainState(s); - } - - /** - * Convenience method that writes a frame to the protocol session. Equivalent to calling - * getProtocolSession().write(). - * - * @param frame the frame to write - */ - public void writeFrame(AMQDataBlock frame) - { - _protocolSession.writeFrame(frame); - } - - public void writeFrame(AMQDataBlock frame, boolean wait) - { - _protocolSession.writeFrame(frame, wait); - } - - /** - * Convenience method that writes a frame to the protocol session and waits for a particular response. Equivalent to - * calling getProtocolSession().write() then waiting for the response. - * - * @param frame - * @param listener the blocking listener. Note the calling thread will block. - */ - public AMQMethodEvent writeCommandFrameAndWaitForReply(AMQFrame frame, - BlockingMethodFrameListener listener) - throws AMQException - { - return writeCommandFrameAndWaitForReply(frame, listener, DEFAULT_SYNC_TIMEOUT); - } - - /** - * Convenience method that writes a frame to the protocol session and waits for a particular response. Equivalent to - * calling getProtocolSession().write() then waiting for the response. - * - * @param frame - * @param listener the blocking listener. Note the calling thread will block. - */ - public AMQMethodEvent writeCommandFrameAndWaitForReply(AMQFrame frame, - BlockingMethodFrameListener listener, long timeout) - throws AMQException - { - try - { - _frameListeners.add(listener); - _protocolSession.writeFrame(frame); - - AMQMethodEvent e = listener.blockForFrame(timeout); - return e; - // When control resumes before this line, a reply will have been received - // that matches the criteria defined in the blocking listener - } - catch (AMQException e) - { - throw e; - } - finally - { - // If we don't removeKey the listener then no-one will - _frameListeners.remove(listener); - } - - } - - /** More convenient method to write a frame and wait for it's response. */ - public AMQMethodEvent syncWrite(AMQFrame frame, Class responseClass) throws AMQException - { - return syncWrite(frame, responseClass, DEFAULT_SYNC_TIMEOUT); - } - - /** More convenient method to write a frame and wait for it's response. */ - public AMQMethodEvent syncWrite(AMQFrame frame, Class responseClass, long timeout) throws AMQException - { - return writeCommandFrameAndWaitForReply(frame, - new SpecificMethodFrameListener(frame.getChannel(), responseClass), timeout); - } - - /** - * Convenience method to register an AMQSession with the protocol handler. Registering a session with the protocol - * handler will ensure that messages are delivered to the consumer(s) on that session. - * - * @param channelId the channel id of the session - * @param session the session instance. - */ - public void addSessionByChannel(int channelId, AMQSession session) - { - _protocolSession.addSessionByChannel(channelId, session); - } - - /** - * Convenience method to deregister an AMQSession with the protocol handler. - * - * @param channelId then channel id of the session - */ - public void removeSessionByChannel(int channelId) - { - _protocolSession.removeSessionByChannel(channelId); - } - - public void closeSession(AMQSession session) throws AMQException - { - _protocolSession.closeSession(session); - } - - public void closeConnection() throws AMQException - { - closeConnection(-1); - } - - public void closeConnection(long timeout) throws AMQException - { - getStateManager().changeState(AMQState.CONNECTION_CLOSING); - - // AMQP version change: Hardwire the version to 0-8 (major=8, minor=0) - // TODO: Connect this to the session version obtained from ProtocolInitiation for this session. - // Be aware of possible changes to parameter order as versions change. - final AMQFrame frame = ConnectionCloseBody.createAMQFrame(0, - _protocolSession.getProtocolMajorVersion(), - _protocolSession.getProtocolMinorVersion(), // AMQP version (major, minor) - 0, // classId - 0, // methodId - AMQConstant.REPLY_SUCCESS.getCode(), // replyCode - new AMQShortString("JMS client is closing the connection.")); // replyText - - try - { - syncWrite(frame, ConnectionCloseOkBody.class, timeout); - _protocolSession.closeProtocolSession(); - } - catch (AMQTimeoutException e) - { - _protocolSession.closeProtocolSession(false); - } - - - } - - /** @return the number of bytes read from this protocol session */ - public long getReadBytes() - { - return _protocolSession.getIoSession().getReadBytes(); - } - - /** @return the number of bytes written to this protocol session */ - public long getWrittenBytes() - { - return _protocolSession.getIoSession().getWrittenBytes(); - } - - public void failover(String host, int port) - { - _failoverHandler.setHost(host); - _failoverHandler.setPort(port); - // see javadoc for FailoverHandler to see rationale for separate thread - startFailoverThread(); - } - - public void blockUntilNotFailingOver() throws InterruptedException - { - if (_failoverLatch != null) - { - _failoverLatch.await(); - } - } - - public AMQShortString generateQueueName() - { - return _protocolSession.generateQueueName(); - } - - public CountDownLatch getFailoverLatch() - { - return _failoverLatch; - } - - public void setFailoverLatch(CountDownLatch failoverLatch) - { - _failoverLatch = failoverLatch; - } - - public AMQConnection getConnection() - { - return _connection; - } - - public AMQStateManager getStateManager() - { - return _stateManager; - } + void writeFrame(AMQDataBlock frame); - public void setStateManager(AMQStateManager stateManager) - { - _stateManager = stateManager; - _protocolSession.setStateManager(stateManager); - } + void closeSession(AMQSession session) throws AMQException; - public AMQProtocolSession getProtocolSession() - { - return _protocolSession; - } + void closeConnection() throws AMQException; - FailoverState getFailoverState() - { - return _failoverState; - } + AMQConnection getConnection(); - public void setFailoverState(FailoverState failoverState) - { - _failoverState = failoverState; - } + AMQStateManager getStateManager(); - public byte getProtocolMajorVersion() - { - return _protocolSession.getProtocolMajorVersion(); - } + AMQProtocolSession getProtocolSession(); + ProtocolOutputHandler getOutputHandler(); - public byte getProtocolMinorVersion() - { - return _protocolSession.getProtocolMinorVersion(); - } + ProtocolVersion getProtocolVersion(); } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandlerImpl.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandlerImpl.java new file mode 100644 index 0000000000..738531d5a5 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolHandlerImpl.java @@ -0,0 +1,537 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.protocol; + +import java.util.Iterator; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.CountDownLatch; + +import org.apache.log4j.Logger; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoHandlerAdapter; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.SSLFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; +import org.apache.qpid.AMQConnectionClosedException; +import org.apache.qpid.AMQDisconnectedException; +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQTimeoutException; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.AMQSession; +import org.apache.qpid.client.SSLConfiguration; +import org.apache.qpid.client.failover.FailoverHandler; +import org.apache.qpid.client.failover.FailoverState; +import org.apache.qpid.client.state.AMQState; +import org.apache.qpid.client.state.AMQStateManager; +import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; +import org.apache.qpid.codec.AMQCodecFactory; +import org.apache.qpid.framing.*; +import org.apache.qpid.pool.ReadWriteThreadModel; +import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.protocol.AMQMethodListener; +import org.apache.qpid.ssl.SSLContextFactory; + + +public class AMQProtocolHandlerImpl extends IoHandlerAdapter implements AMQProtocolHandler +{ + private static final Logger _logger = Logger.getLogger(AMQProtocolHandlerImpl.class); + + /** + * The connection that this protocol handler is associated with. There is a 1-1 mapping between connection instances + * and protocol handler instances. + */ + private AMQConnection _connection; + + /** Our wrapper for a protocol session that provides access to session values in a typesafe manner. */ + private volatile AMQProtocolSession _protocolSession; + + private AMQStateManager _stateManager = new AMQStateManager(); + + + + /** + * We create the failover handler when the session is created since it needs a reference to the IoSession in order + * to be able to send errors during failover back to the client application. The session won't be available in the + * case where we failing over due to a Connection.Redirect message from the broker. + */ + private FailoverHandler _failoverHandler; + + /** + * This flag is used to track whether failover is being attempted. It is used to prevent the application constantly + * attempting failover where it is failing. + */ + private FailoverState _failoverState = FailoverState.NOT_STARTED; + + private CountDownLatch _failoverLatch; + + private final long DEFAULT_SYNC_TIMEOUT = 1000 * 30; + private static final int CONTROL_CHANNEL = 0; + + public AMQProtocolHandlerImpl(AMQConnection con) + { + _connection = con; + } + + public void sessionCreated(IoSession session) throws Exception + { + _logger.debug("Protocol session created for session " + System.identityHashCode(session)); + _failoverHandler = new FailoverHandler(this, session); + + final ProtocolCodecFilter pcf = new ProtocolCodecFilter(new AMQCodecFactory(false)); + + if (Boolean.getBoolean("amqj.shared_read_write_pool")) + { + session.getFilterChain().addBefore("AsynchronousWriteFilter", "protocolFilter", pcf); + } + else + { + session.getFilterChain().addLast("protocolFilter", pcf); + } + // we only add the SSL filter where we have an SSL connection + if (_connection.getSSLConfiguration() != null) + { + SSLConfiguration sslConfig = _connection.getSSLConfiguration(); + SSLContextFactory sslFactory = new SSLContextFactory(sslConfig.getKeystorePath(), sslConfig.getKeystorePassword(), sslConfig.getCertType()); + SSLFilter sslFilter = new SSLFilter(sslFactory.buildClientContext()); + sslFilter.setUseClientMode(true); + session.getFilterChain().addBefore("protocolFilter", "ssl", sslFilter); + } + + + + ReadWriteThreadModel threadModel = ReadWriteThreadModel.getInstance(); + threadModel.getAsynchronousReadFilter().createNewJobForSession(session); + threadModel.getAsynchronousWriteFilter().createNewJobForSession(session); + + + _protocolSession = new AMQProtocolSession(this, session, _connection, getStateManager()); + + // This starts the AMQP initiation by sending the AMQP Header + _protocolSession.init(); + } + + public void sessionOpened(IoSession session) throws Exception + { + + } + + /** + * When the broker connection dies we can either get sessionClosed() called or exceptionCaught() followed by + * sessionClosed() depending on whether we were trying to send data at the time of failure. + * + * @param session + * + * @throws Exception + */ + public void sessionClosed(IoSession session) throws Exception + { + if (_connection.isClosed()) + { + _logger.info("Session closed called by client"); + } + else + { + _logger.info("Session closed called with failover state currently " + _failoverState); + + //reconnetablility was introduced here so as not to disturb the client as they have made their intentions + // known through the policy settings. + + if ((_failoverState != FailoverState.IN_PROGRESS) && _connection.failoverAllowed()) + { + _logger.info("FAILOVER STARTING"); + if (_failoverState == FailoverState.NOT_STARTED) + { + _failoverState = FailoverState.IN_PROGRESS; + startFailoverThread(); + } + else + { + _logger.info("Not starting failover as state currently " + _failoverState); + } + } + else + { + _logger.info("Failover not allowed by policy."); + + if (_logger.isDebugEnabled()) + { + _logger.debug(_connection.getFailoverPolicy().toString()); + } + + if (_failoverState != FailoverState.IN_PROGRESS) + { + _logger.info("sessionClose() not allowed to failover"); + _connection.exceptionReceived( + new AMQDisconnectedException("Server closed connection and reconnection " + + "not permitted.")); + } + else + { + _logger.info("sessionClose() failover in progress"); + } + } + } + + _logger.info("Protocol Session [" + this + "] closed"); + } + + /** See {@link FailoverHandler} to see rationale for separate thread. */ + private void startFailoverThread() + { + Thread failoverThread = new Thread(_failoverHandler); + failoverThread.setName("Failover"); + // Do not inherit daemon-ness from current thread as this can be a daemon + // thread such as a AnonymousIoService thread. + failoverThread.setDaemon(false); + failoverThread.start(); + } + + public void sessionIdle(IoSession session, IdleStatus status) throws Exception + { + _logger.debug("Protocol Session [" + this + ":" + session + "] idle: " + status); + if (IdleStatus.WRITER_IDLE.equals(status)) + { + //write heartbeat frame: + _logger.debug("Sent heartbeat"); + session.write(HeartbeatBody.FRAME); + HeartbeatDiagnostics.sent(); + } + else if (IdleStatus.READER_IDLE.equals(status)) + { + //failover: + HeartbeatDiagnostics.timeout(); + _logger.warn("Timed out while waiting for heartbeat from peer."); + session.close(); + } + } + + public void exceptionCaught(IoSession session, Throwable cause) throws Exception + { + if (_failoverState == FailoverState.NOT_STARTED) + { + //if (!(cause instanceof AMQUndeliveredException) && (!(cause instanceof AMQAuthenticationException))) + if (cause instanceof AMQConnectionClosedException) + { + _logger.info("Exception caught therefore going to attempt failover: " + cause, cause); + // this will attemp failover + + sessionClosed(session); + } + } + // we reach this point if failover was attempted and failed therefore we need to let the calling app + // know since we cannot recover the situation + else if (_failoverState == FailoverState.FAILED) + { + _logger.error("Exception caught by protocol handler: " + cause, cause); + // we notify the state manager of the error in case we have any clients waiting on a state + // change. Those "waiters" will be interrupted and can handle the exception + AMQException amqe = new AMQException("Protocol handler error: " + cause, cause); + propagateExceptionToWaiters(amqe); + _connection.exceptionReceived(cause); + } + } + + /** + * There are two cases where we have other threads potentially blocking for events to be handled by this class. + * These are for the state manager (waiting for a state change) or a frame listener (waiting for a particular type + * of frame to arrive). When an error occurs we need to notify these waiters so that they can react appropriately. + * + * @param e the exception to propagate + */ + public void propagateExceptionToWaiters(Exception e) + { + getStateManager().error(e); + getProtocolSession().getOutputHandler().error(e); + + } + + private static int _messageReceivedCount; + + public void messageReceived(IoSession session, Object message) throws Exception + { + final boolean debug = _logger.isDebugEnabled(); + final long msgNumber = ++_messageReceivedCount; + + if (debug && (msgNumber % 1000 == CONTROL_CHANNEL)) + { + _logger.debug("Received " + _messageReceivedCount + " protocol messages"); + } + + AMQFrame frame = (AMQFrame) message; + + final AMQBody bodyFrame = frame.getBodyFrame(); + + HeartbeatDiagnostics.received(bodyFrame instanceof HeartbeatBody); + + switch (bodyFrame.getFrameType()) + { + case AMQMethodBodyImpl.TYPE: + + if (debug) + { + _logger.debug("(" + System.identityHashCode(this) + ")Method frame received: " + frame); + } + + final AMQMethodEvent evt = new AMQMethodEvent(frame.getChannel(), (AMQMethodBody) bodyFrame); + + try + { + + boolean wasAnyoneInterested = getStateManager().methodReceived(evt); + wasAnyoneInterested = getProtocolSession().getOutputHandler().methodReceived(evt) || wasAnyoneInterested; + + if (!wasAnyoneInterested) + { + throw new AMQException("AMQMethodEvent " + evt + " was not processed by any listener."); + } + } + catch (AMQException e) + { + getStateManager().error(e); + getProtocolSession().getOutputHandler().error(e); + exceptionCaught(session, e); + } + break; + + case ContentHeaderBody.TYPE: + + _protocolSession.messageContentHeaderReceived(frame.getChannel(), + (ContentHeaderBody) bodyFrame); + break; + + case ContentBody.TYPE: + + _protocolSession.messageContentBodyReceived(frame.getChannel(), + (ContentBody) bodyFrame); + break; + + case HeartbeatBody.TYPE: + + if (debug) + { + _logger.debug("Received heartbeat"); + } + break; + + default: + + } + _connection.bytesReceived(_protocolSession.getIoSession().getReadBytes()); + } + + private static int _messagesOut; + + public void messageSent(IoSession session, Object message) throws Exception + { + final long sentMessages = _messagesOut++; + + final boolean debug = _logger.isDebugEnabled(); + + if (debug && (sentMessages % 1000 == CONTROL_CHANNEL)) + { + _logger.debug("Sent " + _messagesOut + " protocol messages"); + } + _connection.bytesSent(session.getWrittenBytes()); + if (debug) + { + _logger.debug("Sent frame " + message); + } + } + + /* + public void addFrameListener(AMQMethodListener listener) + { + _frameListeners.add(listener); + } + + public void removeFrameListener(AMQMethodListener listener) + { + _frameListeners.remove(listener); + } + */ + public void attainState(AMQState s) throws AMQException + { + getStateManager().attainState(s); + } + + /** + * Convenience method that writes a frame to the protocol session. Equivalent to calling + * getProtocolSession().write(). + * + * @param frame the frame to write + */ + public void writeFrame(AMQDataBlock frame) + { + _protocolSession.writeFrame(frame); + } + + + + /** + * Convenience method to register an AMQSession with the protocol handler. Registering a session with the protocol + * handler will ensure that messages are delivered to the consumer(s) on that session. + * + * @param channelId the channel id of the session + * @param session the session instance. + */ + public void addSessionByChannel(int channelId, AMQSession session) + { + _protocolSession.addSessionByChannel(channelId, session); + } + + /** + * Convenience method to deregister an AMQSession with the protocol handler. + * + * @param channelId then channel id of the session + */ + public void removeSessionByChannel(int channelId) + { + _protocolSession.removeSessionByChannel(channelId); + } + + public void closeSession(AMQSession session) throws AMQException + { + _protocolSession.closeSession(session); + } + + public void closeConnection() throws AMQException + { + closeConnection(-1); + } + + public void closeConnection(long timeout) throws AMQException + { + getStateManager().changeState(AMQState.CONNECTION_CLOSING); + + + try + { + ConnectionCloseBody closeBody = getAMQMethodFactory().createConnectionClose(); + sendCommandReceiveResponse(CONTROL_CHANNEL,closeBody); + + + _protocolSession.closeProtocolSession(); + } + catch (AMQTimeoutException e) + { + _protocolSession.closeProtocolSession(false); + } + + + } + + private void sendCommandReceiveResponse(int channelId, AMQMethodBody command) throws AMQException + { + getOutputHandler().sendCommandReceiveResponse(channelId, command); + } + + private AMQMethodFactory getAMQMethodFactory() + { + return getOutputHandler().getAMQMethodFactory(); + } + + /** @return the number of bytes read from this protocol session */ + public long getReadBytes() + { + return _protocolSession.getIoSession().getReadBytes(); + } + + /** @return the number of bytes written to this protocol session */ + public long getWrittenBytes() + { + return _protocolSession.getIoSession().getWrittenBytes(); + } + + public void failover(String host, int port) + { + _failoverHandler.setHost(host); + _failoverHandler.setPort(port); + // see javadoc for FailoverHandler to see rationale for separate thread + startFailoverThread(); + } + + public void blockUntilNotFailingOver() throws InterruptedException + { + if (_failoverLatch != null) + { + _failoverLatch.await(); + } + } + + public AMQShortString generateQueueName() + { + return _protocolSession.generateQueueName(); + } + + public CountDownLatch getFailoverLatch() + { + return _failoverLatch; + } + + public void setFailoverLatch(CountDownLatch failoverLatch) + { + _failoverLatch = failoverLatch; + } + + public AMQConnection getConnection() + { + return _connection; + } + + public AMQStateManager getStateManager() + { + return _stateManager; + } + + public void setStateManager(AMQStateManager stateManager) + { + _stateManager = stateManager; + _protocolSession.setStateManager(stateManager); + } + + public AMQProtocolSession getProtocolSession() + { + return _protocolSession; + } + + public ProtocolOutputHandler getOutputHandler() + { + return getProtocolSession().getOutputHandler(); + } + + FailoverState getFailoverState() + { + return _failoverState; + } + + public void setFailoverState(FailoverState failoverState) + { + _failoverState = failoverState; + } + + public ProtocolVersion getProtocolVersion() + { + return _protocolSession.getProtocolVersion(); + } + + + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java index 055109d3be..3c158415e0 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/AMQProtocolSession.java @@ -43,10 +43,11 @@ import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ContentBody; import org.apache.qpid.framing.ContentHeaderBody; -import org.apache.qpid.framing.MainRegistry; import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersionList; +import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.framing.VersionSpecificRegistry; +import org.apache.qpid.framing.MainRegistry; +import org.apache.qpid.framing.MethodRegistry; import org.apache.qpid.protocol.AMQVersionAwareProtocolSession; import org.apache.qpid.protocol.AMQConstant; @@ -56,7 +57,7 @@ import org.apache.qpid.protocol.AMQConstant; * The underlying protocol session is still available but clients should not * use it to obtain session attributes. */ -public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareProtocolSession +public class AMQProtocolSession implements AMQVersionAwareProtocolSession { protected static final int LAST_WRITE_FUTURE_JOIN_TIMEOUT = 1000 * 60 * 2; @@ -81,7 +82,7 @@ public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareP * The handler from which this session was created and which is used to handle protocol events. * We send failover events to the handler. */ - protected final AMQProtocolHandler _protocolHandler; + protected final AMQProtocolHandlerImpl _protocolHandler; /** * Maps from the channel id to the AMQSession that it represents. @@ -102,9 +103,10 @@ public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareP protected int _queueId = 1; protected final Object _queueIdLock = new Object(); - private byte _protocolMinorVersion; - private byte _protocolMajorVersion; - private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(pv[pv.length-1][PROTOCOL_MAJOR],pv[pv.length-1][PROTOCOL_MINOR]); + private MethodRegistry _registry = MethodRegistry.getMethodRegistry(ProtocolVersion.getLatestSupportedVersion()); + private ProtocolVersion _protocolVersion; + private ProtocolOutputHandler _outputHandler = ProtocolOutputHandlerFactory.createOutputHandler(ProtocolVersion.getLatestSupportedVersion(), this); + ; /** @@ -118,7 +120,7 @@ public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareP _stateManager = new AMQStateManager(this); } - public AMQProtocolSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection) + public AMQProtocolSession(AMQProtocolHandlerImpl protocolHandler, IoSession protocolSession, AMQConnection connection) { _protocolHandler = protocolHandler; _minaProtocolSession = protocolSession; @@ -129,7 +131,7 @@ public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareP _stateManager = new AMQStateManager(this); } - public AMQProtocolSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection, AMQStateManager stateManager) + public AMQProtocolSession(AMQProtocolHandlerImpl protocolHandler, IoSession protocolSession, AMQConnection connection, AMQStateManager stateManager) { _protocolHandler = protocolHandler; _minaProtocolSession = protocolSession; @@ -147,11 +149,8 @@ public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareP { // start the process of setting up the connection. This is the first place that // data is written to the server. - /* Find last protocol version in protocol version list. Make sure last protocol version - listed in the build file (build-module.xml) is the latest version which will be used - here. */ - int i = pv.length - 1; - _minaProtocolSession.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); + + _minaProtocolSession.write(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion())); } public String getClientID() @@ -474,26 +473,27 @@ public class AMQProtocolSession implements ProtocolVersionList, AMQVersionAwareP session.confirmConsumerCancelled(consumerTag); } - public void setProtocolVersion(final byte versionMajor, final byte versionMinor) + public void setProtocolVersion(ProtocolVersion pv) { - _protocolMajorVersion = versionMajor; - _protocolMinorVersion = versionMinor; - _registry = MainRegistry.getVersionSpecificRegistry(versionMajor, versionMinor); + _protocolVersion = pv; + + _registry = MethodRegistry.getMethodRegistry(pv); } - public byte getProtocolMinorVersion() + public ProtocolVersion getProtocolVersion() { - return _protocolMinorVersion; + return _protocolVersion; } - public byte getProtocolMajorVersion() + public MethodRegistry getRegistry() { - return _protocolMajorVersion; + return _registry; } - public VersionSpecificRegistry getRegistry() + public ProtocolOutputHandler getOutputHandler() { - return _registry; + return _outputHandler; } + } diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java b/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java index 85f98eab69..8f1f410a15 100644 --- a/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/BlockingMethodFrameListener.java @@ -23,11 +23,12 @@ package org.apache.qpid.client.protocol; import org.apache.qpid.AMQException; import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.client.failover.FailoverException; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; -public abstract class BlockingMethodFrameListener implements AMQMethodListener +public abstract class BlockingMethodFrameListener implements AMQMethodListener { private volatile boolean _ready = false; @@ -43,7 +44,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener protected int _channelId; - protected AMQMethodEvent _doneEvt = null; + protected AMQMethodEvent _doneEvt = null; public BlockingMethodFrameListener(int channelId) { @@ -91,7 +92,7 @@ public abstract class BlockingMethodFrameListener implements AMQMethodListener /** * This method is called by the thread that wants to wait for a frame. */ - public AMQMethodEvent blockForFrame(long timeout) throws AMQException + public AMQMethodEvent blockForFrame(long timeout) throws AMQException { synchronized (_lock) { diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandler.java b/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandler.java new file mode 100644 index 0000000000..3db6232d41 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandler.java @@ -0,0 +1,58 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.client.protocol; + +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodFactory; +import org.apache.qpid.framing.CommonContentHeaderProperties; +import org.apache.qpid.framing.AMQMethodBodyImpl; +import org.apache.qpid.AMQTimeoutException; +import org.apache.qpid.AMQException; +import org.apache.qpid.protocol.AMQMethodEvent; + +import org.apache.mina.common.ByteBuffer; + +import java.util.Map; +import java.util.HashMap; + + +public interface ProtocolOutputHandler +{ + + void sendCommand(int channelId, AMQMethodBody command); + + AMQMethodBody sendCommandReceiveResponse(int channelId, AMQMethodBody command) throws AMQException; + AMQMethodBody sendCommandReceiveResponse(int channelId, AMQMethodBody command, long timeout) throws AMQException; + T sendCommandReceiveResponse(int channelId, AMQMethodBody command, Class responseClass, long timeout) throws AMQException; + T sendCommandReceiveResponse(int channelId, AMQMethodBody command, Class responseClass) throws AMQException; + + AMQMethodFactory getAMQMethodFactory(); + + void publishMessage(int channelId, AMQShortString exchangeName, AMQShortString routingKey, boolean immediate, boolean mandatory, ByteBuffer payload, CommonContentHeaderProperties contentHeaderProperties, int ticket); + + boolean methodReceived(AMQMethodEvent evt) throws Exception; + + void error(Exception e); +} diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandlerFactory.java b/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandlerFactory.java new file mode 100644 index 0000000000..6cc0d8d3b5 --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/ProtocolOutputHandlerFactory.java @@ -0,0 +1,50 @@ +package org.apache.qpid.client.protocol; + +import org.apache.qpid.framing.ProtocolVersion; +import org.apache.qpid.client.protocol.amqp_8_0.ProtocolOutputHandler_8_0; + +import java.util.Map; +import java.util.HashMap; + +public abstract class ProtocolOutputHandlerFactory +{ + private static final Map _handlers = + new HashMap(); + + public ProtocolOutputHandlerFactory(ProtocolVersion pv) + { + _handlers.put(pv,this); + } + + public abstract ProtocolOutputHandler newInstance(AMQProtocolSession amqProtocolSession); + + public static ProtocolOutputHandler createOutputHandler(ProtocolVersion version, AMQProtocolSession amqProtocolSession) + { + return _handlers.get(version).newInstance(amqProtocolSession); + } + + private static final ProtocolOutputHandlerFactory VERSION_8_0 = + new ProtocolOutputHandlerFactory(new ProtocolVersion((byte)8,(byte)0)) + { + + public ProtocolOutputHandler newInstance(AMQProtocolSession amqProtocolSession) + { + return new ProtocolOutputHandler_8_0(amqProtocolSession); + } + }; + + // TODO - HACK + + private static final ProtocolOutputHandlerFactory VERSION_0_9 = + new ProtocolOutputHandlerFactory(new ProtocolVersion((byte)0,(byte)9)) + { + + public ProtocolOutputHandler newInstance(AMQProtocolSession amqProtocolSession) + { + return new ProtocolOutputHandler_8_0(amqProtocolSession); + } + }; + + + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/protocol/amqp_8_0/ProtocolOutputHandler_8_0.java b/java/client/src/main/java/org/apache/qpid/client/protocol/amqp_8_0/ProtocolOutputHandler_8_0.java new file mode 100644 index 0000000000..3654f46c1a --- /dev/null +++ b/java/client/src/main/java/org/apache/qpid/client/protocol/amqp_8_0/ProtocolOutputHandler_8_0.java @@ -0,0 +1,278 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.client.protocol.amqp_8_0; + +import org.apache.qpid.framing.*; +import org.apache.qpid.framing.amqp_8_0.*; +import org.apache.qpid.client.protocol.ProtocolOutputHandler; +import org.apache.qpid.client.protocol.AMQProtocolSession; +import org.apache.qpid.client.state.listener.SpecificMethodFrameListener; +import org.apache.qpid.AMQTimeoutException; +import org.apache.qpid.AMQException; +import org.apache.qpid.protocol.AMQMethodEvent; +import org.apache.qpid.protocol.AMQMethodListener; + +import org.apache.mina.common.ByteBuffer; + +import java.util.Map; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Collection; +import java.util.concurrent.CopyOnWriteArraySet; + +public class ProtocolOutputHandler_8_0 implements ProtocolOutputHandler +{ + private static final AMQMethodFactory METHOD_FACTORY = new AMQMethodFactory_8_0() ; + + + private static final Map, Class> REQUSET_RESPONSE_METHODBODY_MAP = + new HashMap, Class>(); + + static + { + // Basic Class + REQUSET_RESPONSE_METHODBODY_MAP.put(BasicCancelBody.class, BasicCancelOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(BasicConsumeBody.class, BasicConsumeOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(BasicQosBody.class, BasicQosOkBody.class); + // GET ??? + REQUSET_RESPONSE_METHODBODY_MAP.put(BasicRecoverBody.class, BasicRecoverOkBody.class); + + // Channel Class + REQUSET_RESPONSE_METHODBODY_MAP.put(ChannelCloseBody.class, ChannelCloseOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ChannelFlowBody.class, ChannelFlowOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ChannelOpenBody.class, ChannelOpenOkBody.class); + + // Connection Class + REQUSET_RESPONSE_METHODBODY_MAP.put(ConnectionOpenBody.class, ConnectionOpenOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ConnectionSecureBody.class, ConnectionSecureOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ConnectionStartBody.class, ConnectionStartOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ConnectionTuneBody.class, ConnectionTuneOkBody.class); + + // Exchange Class + REQUSET_RESPONSE_METHODBODY_MAP.put(ExchangeBoundBody.class, ExchangeBoundOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ExchangeDeclareBody.class, ExchangeDeclareOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(ExchangeDeleteBody.class, ExchangeDeleteOkBody.class); + + // Queue Class + REQUSET_RESPONSE_METHODBODY_MAP.put(QueueBindBody.class, QueueBindOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(QueueDeclareBody.class, QueueDeclareOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(QueueDeleteBody.class, QueueDeleteOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(QueuePurgeBody.class, QueuePurgeOkBody.class); + + // Tx Class + REQUSET_RESPONSE_METHODBODY_MAP.put(TxCommitBody.class, TxCommitOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(TxRollbackBody.class, TxRollbackOkBody.class); + REQUSET_RESPONSE_METHODBODY_MAP.put(TxSelectBody.class, TxSelectOkBody.class); + + } + + + + + + private final AMQProtocolSession _session; + private static final long DEFAULT_TIMEOUT = 30000; + private final CopyOnWriteArraySet _frameListeners = + new CopyOnWriteArraySet(); + + public ProtocolOutputHandler_8_0(AMQProtocolSession amqProtocolSession) + { + _session = amqProtocolSession; + } + + + + + private void writeFrame(AMQDataBlock frame) + { + _session.writeFrame(frame); + } + + public void sendCommand(int channelId, AMQMethodBody command) + { + _session.writeFrame(new AMQFrame(channelId,command)); + } + + public AMQMethodBody sendCommandReceiveResponse(int channelId, AMQMethodBody command) throws AMQException + { + return sendCommandReceiveResponse(channelId, command, REQUSET_RESPONSE_METHODBODY_MAP.get(command.getClass())); + } + + public AMQMethodBody sendCommandReceiveResponse(int channelId, AMQMethodBody command, long timeout) throws AMQException + { + return sendCommandReceiveResponse(channelId, command, REQUSET_RESPONSE_METHODBODY_MAP.get(command.getClass()), timeout); + } + + public T sendCommandReceiveResponse(int channelId, AMQMethodBody command, Class responseClass, long timeout) throws AMQException + { + AMQFrame frame = new AMQFrame(channelId,command); + return writeCommandFrameAndWaitForReply(frame, + new SpecificMethodFrameListener(channelId, responseClass), timeout); + } + + private T writeCommandFrameAndWaitForReply(AMQFrame frame, SpecificMethodFrameListener listener, long timeout) throws AMQException + { + try + { + _frameListeners.add(listener); + _session.writeFrame(frame); + + AMQMethodEvent e = listener.blockForFrame(timeout); + return e.getMethod(); + // When control resumes before this line, a reply will have been received + // that matches the criteria defined in the blocking listener + } + finally + { + // If we don't removeKey the listener then no-one will + _frameListeners.remove(listener); + } + + + } + + public T sendCommandReceiveResponse(int channelId, AMQMethodBody command, Class responseClass) throws AMQException + { + return sendCommandReceiveResponse(channelId, command, responseClass, DEFAULT_TIMEOUT); + } + + public AMQMethodFactory getAMQMethodFactory() + { + return METHOD_FACTORY; + } + + + public void publishMessage(int channelId, AMQShortString exchangeName, AMQShortString routingKey, boolean immediate, boolean mandatory, ByteBuffer payload, CommonContentHeaderProperties contentHeaderProperties, int ticket) + { + final int size = (payload != null) ? payload.limit() : 0; + BasicPublishBodyImpl publishBody = new BasicPublishBodyImpl(ticket, exchangeName, routingKey, mandatory, immediate); + + + final int contentBodyFrameCount = calculateContentBodyFrameCount(payload); + final AMQFrame[] frames = new AMQFrame[2 + contentBodyFrameCount]; + + if (payload != null) + { + createContentBodies(payload, frames, 2, channelId); + } + + + + AMQFrame contentHeaderFrame = + ContentHeaderBody.createAMQFrame(channelId, + publishBody.CLASS_ID, + 0, // weight + contentHeaderProperties, + size); + + frames[0] = new AMQFrame(channelId,publishBody); + frames[1] = contentHeaderFrame; + CompositeAMQDataBlock compositeFrame = new CompositeAMQDataBlock(frames); + writeFrame(compositeFrame); + } + + public boolean methodReceived(AMQMethodEvent evt) throws AMQException + { + boolean wasAnyoneInterested = false; + if (!_frameListeners.isEmpty()) + { + Iterator it = _frameListeners.iterator(); + while (it.hasNext()) + { + final SpecificMethodFrameListener listener = it.next(); + wasAnyoneInterested = listener.methodReceived(evt) || wasAnyoneInterested; + } + } + + return wasAnyoneInterested; + } + + public void error(Exception e) + { + if (!_frameListeners.isEmpty()) + { + final Iterator it = _frameListeners.iterator(); + while (it.hasNext()) + { + final SpecificMethodFrameListener ml = it.next(); + ml.error(e); + } + } + } + + + /** + * Create content bodies. This will split a large message into numerous bodies depending on the negotiated + * maximum frame size. + * + * @param payload + * @param frames + * @param offset + * @param channelId @return the array of content bodies + */ + private void createContentBodies(ByteBuffer payload, AMQFrame[] frames, int offset, int channelId) + { + + if (frames.length == (offset + 1)) + { + frames[offset] = ContentBody.createAMQFrame(channelId, new ContentBody(payload)); + } + else + { + + final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize() - 1; + long remaining = payload.remaining(); + for (int i = offset; i < frames.length; i++) + { + payload.position((int) framePayloadMax * (i - offset)); + int length = (remaining >= framePayloadMax) ? (int) framePayloadMax : (int) remaining; + payload.limit(payload.position() + length); + frames[i] = ContentBody.createAMQFrame(channelId, new ContentBody(payload.slice())); + + remaining -= length; + } + } + + } + + private int calculateContentBodyFrameCount(ByteBuffer payload) + { + // we substract one from the total frame maximum size to account for the end of frame marker in a body frame + // (0xCE byte). + int frameCount; + if ((payload == null) || (payload.remaining() == 0)) + { + frameCount = 0; + } + else + { + int dataLength = payload.remaining(); + final long framePayloadMax = _session.getAMQConnection().getMaximumFrameSize() - 1; + int lastFrame = ((dataLength % framePayloadMax) > 0) ? 1 : 0; + frameCount = (int) (dataLength / framePayloadMax) + lastFrame; + } + + return frameCount; + } + + + +} diff --git a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java index 825baf95d1..bba1c2701c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java @@ -27,34 +27,20 @@ import java.util.concurrent.CopyOnWriteArraySet; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.client.handler.BasicCancelOkMethodHandler; -import org.apache.qpid.client.handler.BasicDeliverMethodHandler; -import org.apache.qpid.client.handler.BasicReturnMethodHandler; -import org.apache.qpid.client.handler.ChannelCloseMethodHandler; -import org.apache.qpid.client.handler.ChannelCloseOkMethodHandler; -import org.apache.qpid.client.handler.ChannelFlowOkMethodHandler; -import org.apache.qpid.client.handler.ConnectionCloseMethodHandler; -import org.apache.qpid.client.handler.ConnectionOpenOkMethodHandler; -import org.apache.qpid.client.handler.ConnectionSecureMethodHandler; -import org.apache.qpid.client.handler.ConnectionStartMethodHandler; -import org.apache.qpid.client.handler.ConnectionTuneMethodHandler; -import org.apache.qpid.client.handler.ExchangeBoundOkMethodHandler; -import org.apache.qpid.client.handler.QueueDeleteOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.BasicCancelOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.BasicDeliverMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ChannelCloseOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ChannelFlowOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionOpenOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionTuneMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ExchangeBoundOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.QueueDeleteOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionCloseMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionSecureMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.BasicReturnMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.*; import org.apache.qpid.client.protocol.AMQProtocolSession; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.framing.BasicCancelOkBody; -import org.apache.qpid.framing.BasicDeliverBody; -import org.apache.qpid.framing.BasicReturnBody; -import org.apache.qpid.framing.ChannelCloseBody; -import org.apache.qpid.framing.ChannelCloseOkBody; -import org.apache.qpid.framing.ChannelFlowOkBody; -import org.apache.qpid.framing.ConnectionCloseBody; -import org.apache.qpid.framing.ConnectionOpenOkBody; -import org.apache.qpid.framing.ConnectionSecureBody; -import org.apache.qpid.framing.ConnectionStartBody; -import org.apache.qpid.framing.ConnectionTuneBody; -import org.apache.qpid.framing.ExchangeBoundOkBody; -import org.apache.qpid.framing.QueueDeleteOkBody; +import org.apache.qpid.framing.*; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.protocol.AMQMethodListener; @@ -62,7 +48,7 @@ import org.apache.qpid.protocol.AMQMethodListener; * The state manager is responsible for managing the state of the protocol session.

For each AMQProtocolHandler * there is a separate state manager. */ -public class AMQStateManager implements AMQMethodListener +public class AMQStateManager { private static final Logger _logger = Logger.getLogger(AMQStateManager.class); private AMQProtocolSession _protocolSession; @@ -178,7 +164,7 @@ public class AMQStateManager implements AMQMethodListener StateAwareMethodListener handler = findStateTransitionHandler(_currentState, evt.getMethod()); if (handler != null) { - handler.methodReceived(this, _protocolSession, evt); + handler.methodReceived(this, evt); return true; } return false; diff --git a/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java b/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java index b3932533ce..9ddc50941b 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/StateAwareMethodListener.java @@ -31,6 +31,6 @@ import org.apache.qpid.protocol.AMQMethodEvent; */ public interface StateAwareMethodListener { - void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, - AMQMethodEvent evt) throws AMQException; + void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException; + } diff --git a/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java b/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java index 1c70ded62a..8a19a77776 100644 --- a/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java +++ b/java/client/src/main/java/org/apache/qpid/client/state/listener/SpecificMethodFrameListener.java @@ -22,13 +22,14 @@ package org.apache.qpid.client.state.listener; import org.apache.qpid.AMQException; import org.apache.qpid.client.protocol.BlockingMethodFrameListener; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.framing.AMQMethodBody; -public class SpecificMethodFrameListener extends BlockingMethodFrameListener +public class SpecificMethodFrameListener extends BlockingMethodFrameListener { private final Class _expectedClass; - public SpecificMethodFrameListener(int channelId, Class expectedClass) + public SpecificMethodFrameListener(int channelId, Class expectedClass) { super(channelId); _expectedClass = expectedClass; diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/ITransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/ITransportConnection.java index 7a24d6e15a..9877cd3c37 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/ITransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/ITransportConnection.java @@ -22,11 +22,11 @@ package org.apache.qpid.client.transport; import java.io.IOException; -import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; import org.apache.qpid.jms.BrokerDetails; public interface ITransportConnection { - void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) + void connect(AMQProtocolHandlerImpl protocolHandler, BrokerDetails brokerDetail) throws IOException; } diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java index 04e7e40564..25d5a2cc1c 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/SocketTransportConnection.java @@ -30,7 +30,7 @@ import org.apache.mina.common.IoConnector; import org.apache.mina.common.SimpleByteBufferAllocator; import org.apache.mina.transport.socket.nio.SocketConnectorConfig; import org.apache.mina.transport.socket.nio.SocketSessionConfig; -import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.pool.ReadWriteThreadModel; @@ -50,7 +50,7 @@ public class SocketTransportConnection implements ITransportConnection _socketConnectorFactory = socketConnectorFactory; } - public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) + public void connect(AMQProtocolHandlerImpl protocolHandler, BrokerDetails brokerDetail) throws IOException { ByteBuffer.setUseDirectBuffers(Boolean.getBoolean("amqj.enableDirectBuffers")); diff --git a/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java b/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java index 104c4b43d0..4f8126f070 100644 --- a/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java +++ b/java/client/src/main/java/org/apache/qpid/client/transport/VmPipeTransportConnection.java @@ -27,7 +27,7 @@ import org.apache.mina.common.ConnectFuture; import org.apache.mina.common.IoServiceConfig; import org.apache.mina.transport.vmpipe.VmPipeAddress; import org.apache.mina.transport.vmpipe.VmPipeConnector; -import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; import org.apache.qpid.jms.BrokerDetails; import org.apache.qpid.pool.PoolingFilter; import org.apache.qpid.pool.ReferenceCountingExecutorService; @@ -43,7 +43,7 @@ public class VmPipeTransportConnection implements ITransportConnection _port = port; } - public void connect(AMQProtocolHandler protocolHandler, BrokerDetails brokerDetail) throws IOException + public void connect(AMQProtocolHandlerImpl protocolHandler, BrokerDetails brokerDetail) throws IOException { final VmPipeConnector ioConnector = new VmPipeConnector(); final IoServiceConfig cfg = ioConnector.getDefaultConfig(); diff --git a/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java index 1db7e200bd..b3b26b660a 100644 --- a/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/codec/BasicDeliverTest.java @@ -21,6 +21,8 @@ package org.apache.qpid.codec; import org.apache.qpid.framing.*; +import org.apache.qpid.framing.amqp_8_0.BasicDeliverBodyImpl; + import org.apache.mina.common.*; import org.apache.mina.common.support.BaseIoSession; import org.apache.mina.filter.codec.ProtocolDecoderOutput; @@ -238,7 +240,7 @@ public class BasicDeliverTest return new CompositeAMQDataBlock(frames); } - static AMQFrame wrapBody(AMQBody body) + static AMQFrame wrapBody(AMQBodyImpl body) { AMQFrame frame = new AMQFrame(1, body); return frame; @@ -264,13 +266,11 @@ public class BasicDeliverTest return body; } - static BasicDeliverBody createBasicDeliverBody() + static BasicDeliverBodyImpl createBasicDeliverBody() { - BasicDeliverBody body = new BasicDeliverBody((byte) 8, (byte) 0, - BasicDeliverBody.getClazz((byte) 8, (byte) 0), - BasicDeliverBody.getMethod((byte) 8, (byte) 0), - new AMQShortString("myConsumerTag"), 1, - new AMQShortString("myExchange"), false, + BasicDeliverBodyImpl body = new BasicDeliverBodyImpl( + new AMQShortString("myConsumerTag"), 1,false, + new AMQShortString("myExchange"), new AMQShortString("myRoutingKey")); return body; } diff --git a/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java b/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java index 955f82fab5..1358623bf8 100644 --- a/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java +++ b/java/client/src/old_test/java/org/apache/qpid/framing/FieldTableTest.java @@ -118,8 +118,8 @@ public class FieldTableTest extends TestCase //decode buffer.flip(); - header = new ContentHeaderBody(); - header.populateFromBuffer(buffer, size); + header = new ContentHeaderBody(buffer, size); + return ((BasicContentHeaderProperties) header.properties).getHeaders(); } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java index 5e45d1d537..a0c67b4e74 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseMethodHandlerNoCloseOk.java @@ -46,13 +46,14 @@ public class ChannelCloseMethodHandlerNoCloseOk implements StateAwareMethodListe return _handler; } - public void methodReceived(AMQStateManager stateManager, AMQProtocolSession protocolSession, AMQMethodEvent evt) throws AMQException + public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException { _logger.debug("ChannelClose method received"); + final AMQProtocolSession protocolSession = stateManager.getProtocolSession(); ChannelCloseBody method = (ChannelCloseBody) evt.getMethod(); - AMQConstant errorCode = AMQConstant.getConstant(method.replyCode); - AMQShortString reason = method.replyText; + AMQConstant errorCode = AMQConstant.getConstant(method.getReplyCode()); + AMQShortString reason = method.getReplyText(); if (_logger.isDebugEnabled()) { _logger.debug("Channel close reply code: " + errorCode + ", reason: " + reason); diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java index 3431c56783..d6a4818ff7 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/ChannelCloseTest.java @@ -44,6 +44,9 @@ import org.apache.qpid.framing.ExchangeDeclareBody; import org.apache.qpid.framing.ExchangeDeclareOkBody; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ChannelCloseOkBody; +import org.apache.qpid.framing.amqp_8_0.ChannelCloseOkBodyImpl; +import org.apache.qpid.framing.amqp_8_0.ExchangeDeclareBodyImpl; +import org.apache.qpid.framing.amqp_8_0.ChannelOpenBodyImpl; import org.apache.qpid.AMQException; import org.apache.qpid.AMQTimeoutException; import org.apache.qpid.url.URLSyntaxException; @@ -270,9 +273,7 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con private void sendClose(int channel) { - AMQFrame frame = ChannelCloseOkBody.createAMQFrame(channel, - ((AMQConnection) _connection).getProtocolHandler().getProtocolMajorVersion(), - ((AMQConnection) _connection).getProtocolHandler().getProtocolMinorVersion()); + AMQFrame frame = new AMQFrame(channel, new ChannelCloseOkBodyImpl()); ((AMQConnection) _connection).getProtocolHandler().writeFrame(frame); } @@ -332,37 +333,29 @@ public class ChannelCloseTest extends TestCase implements ExceptionListener, Con private void declareExchange(int channelId, String _type, String _name, boolean nowait) throws AMQException { - AMQFrame exchangeDeclare = ExchangeDeclareBody.createAMQFrame(channelId, - ((AMQConnection) _connection).getProtocolHandler().getProtocolMajorVersion(), - ((AMQConnection) _connection).getProtocolHandler().getProtocolMinorVersion(), - null, // arguments - false, // autoDelete - false, // durable - new AMQShortString(_name), // exchange - false, // internal - nowait, // nowait - true, // passive - 0, // ticket - new AMQShortString(_type)); // type + ExchangeDeclareBody exchangeDeclareBody = + ((AMQConnection) _connection).getProtocolOutputHandler().getAMQMethodFactory().createExchangeDeclare(new AMQShortString(_name),new AMQShortString(_type),0); +// new ExchangeDeclareBodyImpl(0,new AMQShortString(_name),new AMQShortString(_type),true,false,false,false,nowait,null); + + //AMQFrame exchangeDeclare = new AMQFrame(channelId, exchangeDeclareBody); if (nowait) { - ((AMQConnection) _connection).getProtocolHandler().writeFrame(exchangeDeclare); + ((AMQConnection) _connection).getProtocolOutputHandler().sendCommand(channelId, exchangeDeclareBody); + } else { - ((AMQConnection) _connection).getProtocolHandler().syncWrite(exchangeDeclare, ExchangeDeclareOkBody.class, SYNC_TIMEOUT); + ((AMQConnection) _connection).getProtocolOutputHandler().sendCommandReceiveResponse(channelId, exchangeDeclareBody, SYNC_TIMEOUT); } } private void createChannel(int channelId) throws AMQException { - ((AMQConnection) _connection).getProtocolHandler().syncWrite( - ChannelOpenBody.createAMQFrame(channelId, - ((AMQConnection) _connection).getProtocolHandler().getProtocolMajorVersion(), - ((AMQConnection) _connection).getProtocolHandler().getProtocolMinorVersion(), - null), // outOfBand - ChannelOpenOkBody.class); + + ChannelOpenBody openBody = + ((AMQConnection) _connection).getProtocolOutputHandler().getAMQMethodFactory().createChannelOpen(); + ((AMQConnection) _connection).getProtocolOutputHandler().sendCommandReceiveResponse(channelId, openBody); } diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java index d128f30727..29a8ecf5c1 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/channelclose/NoCloseOKStateManager.java @@ -22,18 +22,14 @@ package org.apache.qpid.test.unit.client.channelclose; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.AMQState; -import org.apache.qpid.client.handler.ConnectionStartMethodHandler; -import org.apache.qpid.client.handler.ConnectionCloseMethodHandler; -import org.apache.qpid.client.handler.ConnectionTuneMethodHandler; -import org.apache.qpid.client.handler.ConnectionSecureMethodHandler; -import org.apache.qpid.client.handler.ConnectionOpenOkMethodHandler; -import org.apache.qpid.client.handler.ChannelCloseOkMethodHandler; -import org.apache.qpid.client.handler.BasicDeliverMethodHandler; -import org.apache.qpid.client.handler.BasicReturnMethodHandler; -import org.apache.qpid.client.handler.BasicCancelOkMethodHandler; -import org.apache.qpid.client.handler.ChannelFlowOkMethodHandler; -import org.apache.qpid.client.handler.QueueDeleteOkMethodHandler; -import org.apache.qpid.client.handler.ExchangeBoundOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionTuneMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ChannelCloseOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.BasicDeliverMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ChannelFlowOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ExchangeBoundOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.BasicReturnMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionStartMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.*; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.framing.ConnectionStartBody; import org.apache.qpid.framing.ConnectionCloseBody; diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java index 4374329fb0..bf7ea4f50b 100644 --- a/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java +++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/protocol/AMQProtocolSessionTest.java @@ -24,7 +24,7 @@ import junit.framework.TestCase; import org.apache.mina.common.IoSession; import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.protocol.AMQProtocolHandler; +import org.apache.qpid.client.protocol.AMQProtocolHandlerImpl; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.framing.AMQShortString; @@ -36,7 +36,7 @@ public class AMQProtocolSessionTest extends TestCase { } - public AMQProtSession(AMQProtocolHandler protocolHandler, IoSession protocolSession, AMQConnection connection) + public AMQProtSession(AMQProtocolHandlerImpl protocolHandler, IoSession protocolSession, AMQConnection connection) { super(protocolHandler,protocolSession,connection); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQConnectionWaitException.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQConnectionWaitException.java new file mode 100644 index 0000000000..4d2737edce --- /dev/null +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQConnectionWaitException.java @@ -0,0 +1,32 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.cluster; + +import org.apache.qpid.AMQException; + +public class AMQConnectionWaitException extends AMQException +{ + public AMQConnectionWaitException(String s, Throwable e) + { + super(s, e); + + } +} diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedBodyTypeException.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedBodyTypeException.java new file mode 100644 index 0000000000..3681fac750 --- /dev/null +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedBodyTypeException.java @@ -0,0 +1,33 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.cluster; + +import org.apache.qpid.AMQException; +import org.apache.qpid.framing.AMQBodyImpl; + +public class AMQUnexpectedBodyTypeException extends AMQException +{ + + public AMQUnexpectedBodyTypeException(Class expectedClass, AMQBodyImpl body) + { + super("Unexpected body type. Expected: " + expectedClass.getName() + "; got: " + body.getClass().getName()); + } +} diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedFrameTypeException.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedFrameTypeException.java new file mode 100644 index 0000000000..721da24d53 --- /dev/null +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/AMQUnexpectedFrameTypeException.java @@ -0,0 +1,31 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.cluster; + +import org.apache.qpid.AMQException; + +public class AMQUnexpectedFrameTypeException extends AMQException +{ + public AMQUnexpectedFrameTypeException(String s) + { + super(s); + } +} diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/BlockingHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/BlockingHandler.java index 39508df566..aeded15eb8 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/BlockingHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/BlockingHandler.java @@ -20,26 +20,26 @@ */ package org.apache.qpid.server.cluster; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; public class BlockingHandler implements ResponseHandler { private final Class _expected; private boolean _completed; - private AMQMethodBody _response; + private AMQMethodBodyImpl _response; public BlockingHandler() { - this(AMQMethodBody.class); + this(AMQMethodBodyImpl.class); } - public BlockingHandler(Class expected) + public BlockingHandler(Class expected) { _expected = expected; } - public void responded(AMQMethodBody response) + public void responded(AMQMethodBodyImpl response) { if (_expected.isInstance(response)) { @@ -74,7 +74,7 @@ public class BlockingHandler implements ResponseHandler } } - AMQMethodBody getResponse() + AMQMethodBodyImpl getResponse() { return _response; } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/Broker.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/Broker.java index 7e2cf6da83..c560a1e20c 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/Broker.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/Broker.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.cluster; import org.apache.qpid.AMQException; import org.apache.qpid.server.cluster.util.LogMessage; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.log4j.Logger; import java.io.IOException; @@ -88,7 +88,7 @@ abstract class Broker extends SimpleMemberHandle implements Member * @param response the response received * @return true if the response matched an outstanding request */ - protected synchronized boolean handleResponse(int channel, AMQMethodBody response) + protected synchronized boolean handleResponse(int channel, AMQMethodBodyImpl response) { ResponseHandler request = _requests.get(channel); if (request == null) @@ -174,7 +174,7 @@ abstract class Broker extends SimpleMemberHandle implements Member /** * Start connection process, including replay */ - abstract void connectAsynch(Iterable msgs); + abstract void connectAsynch(Iterable msgs); /** * Replay messages to the remote peer this instance represents. These messages @@ -182,7 +182,7 @@ abstract class Broker extends SimpleMemberHandle implements Member * * @param msgs */ - abstract void replay(Iterable msgs); + abstract void replay(Iterable msgs); /** * establish connection, handling redirect if required... @@ -200,7 +200,7 @@ abstract class Broker extends SimpleMemberHandle implements Member this.channel = channel; } - public void responded(AMQMethodBody response) + public void responded(AMQMethodBodyImpl response) { request.responseReceived(Broker.this, response); _requests.remove(channel); @@ -228,7 +228,7 @@ abstract class Broker extends SimpleMemberHandle implements Member this.channel = channel; } - public void responded(AMQMethodBody response) + public void responded(AMQMethodBodyImpl response) { handler.responded(response); _requests.remove(channel); diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/BrokerGroup.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/BrokerGroup.java index 755a341607..03de4fbbb7 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/BrokerGroup.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/BrokerGroup.java @@ -24,7 +24,7 @@ import org.apache.log4j.Logger; import org.apache.qpid.server.cluster.replay.ReplayManager; import org.apache.qpid.server.cluster.util.LogMessage; import org.apache.qpid.server.cluster.util.InvokeMultiple; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import java.io.IOException; import java.util.ArrayList; @@ -225,7 +225,7 @@ class BrokerGroup if (create) { Broker b = _factory.create(handle); - List msgs = _replayMgr.replay(isLeader(_local)); + List msgs = _replayMgr.replay(isLeader(_local)); _logger.info(new LogMessage("Replaying {0} from {1} to {2}", msgs, _local, b)); b.connectAsynch(msgs); diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientAdapter.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientAdapter.java index 1b4a3e8327..e3377d3ed1 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientAdapter.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientAdapter.java @@ -26,7 +26,7 @@ import org.apache.qpid.client.AMQConnection; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.client.protocol.AMQProtocolSession; import org.apache.qpid.client.state.AMQStateManager; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; /** * Hack to assist with reuse of the client handlers for connection setup in @@ -49,7 +49,7 @@ class ClientAdapter implements MethodHandler _stateMgr = stateMgr; } - public void handle(int channel, AMQMethodBody method) throws AMQException + public void handle(int channel, AMQMethodBodyImpl method) throws AMQException { AMQMethodEvent evt = new AMQMethodEvent(channel, method); _stateMgr.methodReceived(evt); diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java index 5300912716..fb9e1fa70c 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClientHandlerRegistry.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.cluster; -import org.apache.qpid.client.handler.ConnectionCloseMethodHandler; -import org.apache.qpid.client.handler.ConnectionOpenOkMethodHandler; -import org.apache.qpid.client.handler.ConnectionSecureMethodHandler; -import org.apache.qpid.client.handler.ConnectionStartMethodHandler; -import org.apache.qpid.client.handler.ConnectionTuneMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionCloseMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionOpenOkMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionSecureMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionTuneMethodHandler; +import org.apache.qpid.client.handler.amqp_8_0.ConnectionStartMethodHandler; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.client.state.AMQStateManager; import org.apache.qpid.client.state.IllegalStateTransitionException; @@ -78,14 +78,14 @@ public class ClientHandlerRegistry extends AMQStateManager return registry; } - protected StateAwareMethodListener findStateTransitionHandler(AMQState state, AMQMethodBody frame) throws IllegalStateTransitionException + protected StateAwareMethodListener findStateTransitionHandler(AMQState state, AMQMethodBodyImpl frame) throws IllegalStateTransitionException { ClientRegistry registry = _handlers.get(state); return registry == null ? null : registry.getHandler(frame); } - > void addHandlers(Class type, StateAwareMethodListener handler, AMQState... states) + > void addHandlers(Class type, StateAwareMethodListener handler, AMQState... states) { for (AMQState state : states) { @@ -93,7 +93,7 @@ public class ClientHandlerRegistry extends AMQStateManager } } - > void addHandler(Class type, StateAwareMethodListener handler, AMQState state) + > void addHandler(Class type, StateAwareMethodListener handler, AMQState state) { ClientRegistry registry = _handlers.get(state); if (registry == null) @@ -106,15 +106,15 @@ public class ClientHandlerRegistry extends AMQStateManager static class ClientRegistry { - private final Map, StateAwareMethodListener> registry - = new HashMap, StateAwareMethodListener>(); + private final Map, StateAwareMethodListener> registry + = new HashMap, StateAwareMethodListener>(); - > void add(A type, StateAwareMethodListener handler) + > void add(A type, StateAwareMethodListener handler) { registry.put(type, handler); } - StateAwareMethodListener getHandler(AMQMethodBody frame) + StateAwareMethodListener getHandler(AMQMethodBodyImpl frame) { return registry.get(frame.getClass()); } @@ -122,9 +122,9 @@ public class ClientHandlerRegistry extends AMQStateManager class ConnectionTuneHandler extends ConnectionTuneMethodHandler { - protected AMQFrame createConnectionOpenFrame(int channel, AMQShortString path, AMQShortString capabilities, boolean insist, byte major, byte minor) + protected AMQFrame createConnectionOpenBody(int channel, AMQShortString path, AMQShortString capabilities, boolean insist, byte major, byte minor) { - return super.createConnectionOpenFrame(channel, path, new AMQShortString(ClusterCapability.add(capabilities, _identity)), insist, major, minor); + return super.createConnectionOpenBody(channel, path, new AMQShortString(ClusterCapability.add(capabilities, _identity)), insist, major, minor); } } } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClusteredProtocolHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClusteredProtocolHandler.java index ee5aa48db9..4e0a367f40 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClusteredProtocolHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ClusteredProtocolHandler.java @@ -24,17 +24,14 @@ import org.apache.log4j.Logger; import org.apache.mina.common.IoSession; import org.apache.qpid.AMQException; import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.AMQBody; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.ConnectionOpenBody; import org.apache.qpid.framing.ConnectionSecureOkBody; import org.apache.qpid.framing.ConnectionStartOkBody; import org.apache.qpid.framing.ConnectionTuneOkBody; import org.apache.qpid.framing.ClusterMembershipBody; -import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.protocol.AMQPFastProtocolHandler; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.cluster.util.LogMessage; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/DefaultGroupManager.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/DefaultGroupManager.java index 2f473b63fb..149378a626 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/DefaultGroupManager.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/DefaultGroupManager.java @@ -230,7 +230,7 @@ public class DefaultGroupManager implements GroupManager, MemberFailureListener, //connect to the host and port specified: Broker prospect = connectToProspect(member); announceMembership(); - List msgs = _replayMgr.replay(true); + List msgs = _replayMgr.replay(true); _logger.info(new LogMessage("Replaying {0} from leader to {1}", msgs, prospect)); prospect.replay(msgs); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupRequest.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupRequest.java index 8ab7856e87..55b51bf736 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupRequest.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupRequest.java @@ -21,7 +21,7 @@ package org.apache.qpid.server.cluster; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import java.util.ArrayList; import java.util.HashMap; @@ -35,7 +35,7 @@ import java.util.Map; */ class GroupRequest { - private final Map _responses = new HashMap(); + private final Map _responses = new HashMap(); private final List _brokers = new ArrayList(); private boolean _sent; @@ -62,7 +62,7 @@ class GroupRequest return checkCompletion(); } - public boolean responseReceived(Member broker, AMQMethodBody response) + public boolean responseReceived(Member broker, AMQMethodBodyImpl response) { _responses.put(broker, response); return checkCompletion(); @@ -90,9 +90,9 @@ class GroupRequest return true; } - List getResults() + List getResults() { - List results = new ArrayList(_brokers.size()); + List results = new ArrayList(_brokers.size()); for (Member b : _brokers) { results.add(_responses.get(b)); diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupResponseHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupResponseHandler.java index d2e9de2f39..d394651c26 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupResponseHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/GroupResponseHandler.java @@ -20,12 +20,12 @@ */ package org.apache.qpid.server.cluster; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import java.util.List; public interface GroupResponseHandler { //Note: this implies that the response to a group request will always be a method body... - public void response(List responses, List members); + public void response(List responses, List members); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandler.java index a83f034021..d3f2b9201c 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandler.java @@ -21,9 +21,9 @@ package org.apache.qpid.server.cluster; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; interface MethodHandler { - public void handle(int channel, AMQMethodBody method) throws AMQException; + public void handle(int channel, AMQMethodBodyImpl method) throws AMQException; } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandlerRegistry.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandlerRegistry.java index 748a660bb8..33ec771d6a 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandlerRegistry.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/MethodHandlerRegistry.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.server.cluster; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.state.StateAwareMethodListener; import java.util.HashMap; @@ -28,16 +28,16 @@ import java.util.Map; public class MethodHandlerRegistry { - private final Map, StateAwareMethodListener> registry = - new HashMap, StateAwareMethodListener>(); + private final Map, StateAwareMethodListener> registry = + new HashMap, StateAwareMethodListener>(); - public > MethodHandlerRegistry addHandler(B type, StateAwareMethodListener handler) + public > MethodHandlerRegistry addHandler(B type, StateAwareMethodListener handler) { registry.put(type, handler); return this; } - public StateAwareMethodListener getHandler(B frame) + public StateAwareMethodListener getHandler(B frame) { return (StateAwareMethodListener) registry.get(frame.getClass()); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/MinaBrokerProxy.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/MinaBrokerProxy.java index 401a54444b..1f736ad94c 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/MinaBrokerProxy.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/MinaBrokerProxy.java @@ -33,13 +33,13 @@ import org.apache.qpid.AMQException; import org.apache.qpid.server.cluster.util.LogMessage; import org.apache.qpid.client.state.AMQState; import org.apache.qpid.codec.AMQCodecFactory; -import org.apache.qpid.framing.AMQBody; +import org.apache.qpid.framing.AMQBodyImpl; import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.framing.ConnectionRedirectBody; import org.apache.qpid.framing.ProtocolInitiation; -import org.apache.qpid.framing.ProtocolVersionList; +import org.apache.qpid.framing.ProtocolVersion; import java.io.IOException; import java.net.InetSocketAddress; @@ -57,7 +57,7 @@ public class MinaBrokerProxy extends Broker implements MethodHandler private final MemberHandle _local; private IoSession _session; private MethodHandler _handler; - private Iterable _replay; + private Iterable _replay; MinaBrokerProxy(String host, int port, MemberHandle local) { @@ -106,13 +106,13 @@ public class MinaBrokerProxy extends Broker implements MethodHandler return _connectionMonitor.waitUntilOpen(); } - void connectAsynch(Iterable msgs) + void connectAsynch(Iterable msgs) { _replay = msgs; connectImpl(); } - void replay(Iterable msgs) + void replay(Iterable msgs) { _replay = msgs; if(_connectionMonitor.isOpened()) @@ -138,7 +138,7 @@ public class MinaBrokerProxy extends Broker implements MethodHandler } } - public void send(AMQDataBlock data) throws AMQException + public void send(AMQDataBlock data) throws AMQConnectionWaitException { if (_session == null) { @@ -146,9 +146,9 @@ public class MinaBrokerProxy extends Broker implements MethodHandler { _connectionMonitor.waitUntilOpen(); } - catch (Exception e) + catch (InterruptedException e) { - throw new AMQException("Failed to send " + data + ": " + e, e); + throw new AMQConnectionWaitException("Failed to send " + data + ": " + e, e); } } _session.write(data); @@ -158,14 +158,14 @@ public class MinaBrokerProxy extends Broker implements MethodHandler { if(_replay != null) { - for(AMQMethodBody b : _replay) + for(AMQMethodBodyImpl b : _replay) { _session.write(new AMQFrame(0, b)); } } } - public void handle(int channel, AMQMethodBody method) throws AMQException + public void handle(int channel, AMQMethodBodyImpl method) throws AMQException { _logger.info(new LogMessage("Handling method: {0} for channel {1}", method, channel)); if (!handleResponse(channel, method)) @@ -174,7 +174,7 @@ public class MinaBrokerProxy extends Broker implements MethodHandler } } - private void handleMethod(int channel, AMQMethodBody method) throws AMQException + private void handleMethod(int channel, AMQMethodBodyImpl method) throws AMQException { if (method instanceof ConnectionRedirectBody) { @@ -200,14 +200,14 @@ public class MinaBrokerProxy extends Broker implements MethodHandler private void handleFrame(AMQFrame frame) throws AMQException { - AMQBody body = frame.getBodyFrame(); - if (body instanceof AMQMethodBody) + AMQBodyImpl body = frame.getBodyFrame(); + if (body instanceof AMQMethodBodyImpl) { - handleMethod(frame.getChannel(), (AMQMethodBody) body); + handleMethod(frame.getChannel(), (AMQMethodBodyImpl) body); } else { - throw new AMQException("Client only expects method body, got: " + body); + throw new AMQUnexpectedBodyTypeException(AMQMethodBodyImpl.class, body); } } @@ -216,7 +216,7 @@ public class MinaBrokerProxy extends Broker implements MethodHandler return "MinaBrokerProxy[" + (_session == null ? super.toString() : _session.getRemoteAddress()) + "]"; } - private class MinaBinding extends IoHandlerAdapter implements ProtocolVersionList + private class MinaBinding extends IoHandlerAdapter { public void sessionCreated(IoSession session) throws Exception { @@ -228,8 +228,8 @@ public class MinaBrokerProxy extends Broker implements MethodHandler /* Find last protocol version in protocol version list. Make sure last protocol version listed in the build file (build-module.xml) is the latest version which will be used here. */ - int i = pv.length - 1; - session.write(new ProtocolInitiation(pv[i][PROTOCOL_MAJOR], pv[i][PROTOCOL_MINOR])); + + session.write(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion())); } public void sessionOpened(IoSession session) throws Exception @@ -260,7 +260,7 @@ public class MinaBrokerProxy extends Broker implements MethodHandler } else { - throw new AMQException("Received message of unrecognised type: " + object); + throw new AMQUnexpectedFrameTypeException("Received message of unrecognised type: " + object); } } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ResponseHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ResponseHandler.java index fe76ca6505..81341eb445 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ResponseHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ResponseHandler.java @@ -20,11 +20,11 @@ */ package org.apache.qpid.server.cluster; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; public interface ResponseHandler { - public void responded(AMQMethodBody response); + public void responded(AMQMethodBodyImpl response); public void removed(); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ServerHandlerRegistry.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ServerHandlerRegistry.java index 03b0dc7f2e..ac0373cc0d 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/ServerHandlerRegistry.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/ServerHandlerRegistry.java @@ -21,14 +21,12 @@ package org.apache.qpid.server.cluster; import org.apache.log4j.Logger; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.state.AMQState; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.IllegalStateTransitionException; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.cluster.util.LogMessage; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; @@ -74,7 +72,7 @@ class ServerHandlerRegistry extends AMQStateManager } } - protected StateAwareMethodListener findStateTransitionHandler(AMQState state, B frame) throws IllegalStateTransitionException + protected StateAwareMethodListener findStateTransitionHandler(AMQState state, B frame) throws IllegalStateTransitionException { MethodHandlerRegistry registry = _handlers.get(state); StateAwareMethodListener handler = (registry == null) ? null : registry.getHandler(frame); @@ -85,7 +83,7 @@ class ServerHandlerRegistry extends AMQStateManager return handler; } - > void addHandler(AMQState state, B type, StateAwareMethodListener handler) + > void addHandler(AMQState state, B type, StateAwareMethodListener handler) { MethodHandlerRegistry registry = _handlers.get(state); if (registry == null) diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java index f7c40c60b3..bae930b341 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/SimpleBodySendable.java @@ -18,16 +18,16 @@ package org.apache.qpid.server.cluster; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQBody; +import org.apache.qpid.framing.AMQBodyImpl; import org.apache.qpid.framing.AMQFrame; /** */ public class SimpleBodySendable implements Sendable { - private final AMQBody _body; + private final AMQBodyImpl _body; - public SimpleBodySendable(AMQBody body) + public SimpleBodySendable(AMQBodyImpl body) { _body = body; } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ChainedClusterMethodHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ChainedClusterMethodHandler.java index 86710e8a31..85955ab775 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ChainedClusterMethodHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ChainedClusterMethodHandler.java @@ -21,18 +21,14 @@ package org.apache.qpid.server.cluster.handler; import org.apache.qpid.server.state.AMQStateManager; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import java.util.List; import java.util.ArrayList; -public class ChainedClusterMethodHandler extends ClusterMethodHandler +public class ChainedClusterMethodHandler extends ClusterMethodHandler { private final List> _handlers; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandler.java index faab99b0f6..5c7e1d7ff7 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandler.java @@ -20,17 +20,15 @@ */ package org.apache.qpid.server.cluster.handler; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.state.AMQStateManager; -import org.apache.qpid.server.queue.QueueRegistry; -import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.cluster.ClusteredProtocolSession; import org.apache.qpid.AMQException; -public abstract class ClusterMethodHandler implements StateAwareMethodListener +public abstract class ClusterMethodHandler implements StateAwareMethodListener { public final void methodReceived(AMQStateManager stateMgr, AMQMethodEvent evt) throws AMQException { diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandlerFactory.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandlerFactory.java index e7509da32a..313ba6d304 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandlerFactory.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ClusterMethodHandlerFactory.java @@ -222,17 +222,17 @@ public class ClusterMethodHandlerFactory implements MethodHandlerFactory } } - private ReplicatingHandler replicated(StateAwareMethodListener handler) + private ReplicatingHandler replicated(StateAwareMethodListener handler) { return new ReplicatingHandler(_groupMgr, handler); } - private StateAwareMethodListener alternate(StateAwareMethodListener peer, StateAwareMethodListener client) + private StateAwareMethodListener alternate(StateAwareMethodListener peer, StateAwareMethodListener client) { return new PeerHandler(peer, client); } - private StateAwareMethodListener chain(ClusterMethodHandler... h) + private StateAwareMethodListener chain(ClusterMethodHandler... h) { return new ChainedClusterMethodHandler(h); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ExtendedHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ExtendedHandler.java index a2f62f714b..a9cb096d33 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ExtendedHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ExtendedHandler.java @@ -21,15 +21,12 @@ package org.apache.qpid.server.cluster.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.server.exchange.ExchangeRegistry; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -class ExtendedHandler implements StateAwareMethodListener +class ExtendedHandler implements StateAwareMethodListener { private final StateAwareMethodListener _base; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/NullListener.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/NullListener.java index 8b0bb4b127..a0b95344ee 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/NullListener.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/NullListener.java @@ -21,15 +21,12 @@ package org.apache.qpid.server.cluster.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.server.exchange.ExchangeRegistry; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -public class NullListener implements StateAwareMethodListener +public class NullListener implements StateAwareMethodListener { public void methodReceived(AMQStateManager stateManager, AMQMethodEvent evt) throws AMQException { diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/PeerHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/PeerHandler.java index 447e51ccd9..50f25bd7fe 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/PeerHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/PeerHandler.java @@ -21,12 +21,8 @@ package org.apache.qpid.server.cluster.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.server.cluster.ClusteredProtocolSession; -import org.apache.qpid.server.exchange.ExchangeRegistry; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; @@ -36,7 +32,7 @@ import org.apache.qpid.server.state.StateAwareMethodListener; * application). * */ -public class PeerHandler extends ClusterMethodHandler +public class PeerHandler extends ClusterMethodHandler { private final StateAwareMethodListener _peer; private final StateAwareMethodListener _client; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ReplicatingHandler.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ReplicatingHandler.java index 888fa4e426..f7b9eb2b21 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ReplicatingHandler.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/ReplicatingHandler.java @@ -22,7 +22,7 @@ package org.apache.qpid.server.cluster.handler; import org.apache.log4j.Logger; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.cluster.util.LogMessage; import org.apache.qpid.server.cluster.*; import org.apache.qpid.server.cluster.policy.StandardPolicies; @@ -41,7 +41,7 @@ import java.util.List; * processed locally after 'completion' of this broadcast. * */ -class ReplicatingHandler extends ClusterMethodHandler implements StandardPolicies +class ReplicatingHandler extends ClusterMethodHandler implements StandardPolicies { protected static final Logger _logger = Logger.getLogger(ReplicatingHandler.class); @@ -109,7 +109,7 @@ class ReplicatingHandler extends ClusterMethodHandler responses, List members) + public void response(List responses, List members) { try { diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappedListener.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappedListener.java index 8b0c638d63..9ad8b52c83 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappedListener.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappedListener.java @@ -21,15 +21,12 @@ package org.apache.qpid.server.cluster.handler; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; -import org.apache.qpid.server.exchange.ExchangeRegistry; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; -public class WrappedListener implements StateAwareMethodListener +public class WrappedListener implements StateAwareMethodListener { private final StateAwareMethodListener _primary; private final StateAwareMethodListener _post; @@ -49,7 +46,7 @@ public class WrappedListener implements StateAwareMetho _post.methodReceived(stateMgr, evt); } - private static StateAwareMethodListener check(StateAwareMethodListener in) + private static StateAwareMethodListener check(StateAwareMethodListener in) { return in == null ? new NullListener() : in; } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappingMethodHandlerFactory.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappingMethodHandlerFactory.java index 5ec3c9660a..47cec07546 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappingMethodHandlerFactory.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/handler/WrappingMethodHandlerFactory.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.server.cluster.handler; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.cluster.MethodHandlerFactory; import org.apache.qpid.server.cluster.MethodHandlerRegistry; import org.apache.qpid.server.state.AMQState; @@ -66,12 +66,12 @@ public abstract class WrappingMethodHandlerFactory implements MethodHandlerFacto return registry; } - private > void wrap(MethodHandlerRegistry r, B type, A frame) + private > void wrap(MethodHandlerRegistry r, B type, A frame) { r.addHandler(type, new WrappedListener(r.getHandler(frame), _pre, _post)); } - protected static class FrameDescriptor> + protected static class FrameDescriptor> { protected final A instance; protected final B type; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ChainedMethodRecorder.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ChainedMethodRecorder.java index 3664be58bc..22e95308d7 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ChainedMethodRecorder.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ChainedMethodRecorder.java @@ -20,9 +20,9 @@ */ package org.apache.qpid.server.cluster.replay; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; -abstract class ChainedMethodRecorder implements MethodRecorder +abstract class ChainedMethodRecorder implements MethodRecorder { private final MethodRecorder _recorder; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ConsumerCounts.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ConsumerCounts.java index 5a433b869b..d3bf72b4fd 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ConsumerCounts.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ConsumerCounts.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.server.cluster.replay; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.framing.BasicConsumeBody; import org.apache.qpid.framing.AMQShortString; @@ -48,7 +48,7 @@ class ConsumerCounts return count == null ? 0 : count; } - synchronized void replay(List messages) + synchronized void replay(List messages) { for(AMQShortString queue : _counts.keySet()) { @@ -72,7 +72,7 @@ class ConsumerCounts } } - private void replay(BasicConsumeBody msg, List messages) + private void replay(BasicConsumeBody msg, List messages) { int count = _counts.get(msg.queue); for(int i = 0; i < count; i++) diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/MethodRecorder.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/MethodRecorder.java index e45810438e..421da7e9ea 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/MethodRecorder.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/MethodRecorder.java @@ -20,13 +20,13 @@ */ package org.apache.qpid.server.cluster.replay; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; /** * Abstraction through which a method can be recorded for replay * */ -interface MethodRecorder +interface MethodRecorder { public void record(T method); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/RecordingMethodHandlerFactory.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/RecordingMethodHandlerFactory.java index 4d3fe1dbed..4467be4052 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/RecordingMethodHandlerFactory.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/RecordingMethodHandlerFactory.java @@ -20,8 +20,6 @@ */ package org.apache.qpid.server.cluster.replay; -import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQMethodBody; import org.apache.qpid.framing.BasicCancelBody; import org.apache.qpid.framing.BasicConsumeBody; import org.apache.qpid.framing.ExchangeDeclareBody; @@ -30,15 +28,8 @@ import org.apache.qpid.framing.QueueBindBody; import org.apache.qpid.framing.QueueDeclareBody; import org.apache.qpid.framing.QueueDeleteBody; import org.apache.qpid.server.cluster.MethodHandlerFactory; -import org.apache.qpid.server.cluster.MethodHandlerRegistry; import org.apache.qpid.server.cluster.handler.WrappingMethodHandlerFactory; -import org.apache.qpid.server.exchange.ExchangeRegistry; -import org.apache.qpid.protocol.AMQMethodEvent; -import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQState; -import org.apache.qpid.server.state.AMQStateManager; -import org.apache.qpid.server.state.StateAwareMethodListener; import java.util.Arrays; diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayManager.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayManager.java index 898cb80cb3..799a88b265 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayManager.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayManager.java @@ -20,9 +20,7 @@ */ package org.apache.qpid.server.cluster.replay; -import org.apache.qpid.server.cluster.Sendable; -import org.apache.qpid.framing.AMQDataBlock; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import java.util.List; @@ -33,5 +31,5 @@ import java.util.List; */ public interface ReplayManager { - public List replay(boolean isLeader); + public List replay(boolean isLeader); } diff --git a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java index d7bbb1c36b..5dfb02c7c5 100644 --- a/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java +++ b/java/cluster/src/main/java/org/apache/qpid/server/cluster/replay/ReplayStore.java @@ -26,10 +26,8 @@ import org.apache.qpid.framing.*; import org.apache.qpid.server.cluster.ClusteredProtocolSession; import org.apache.qpid.server.cluster.util.LogMessage; import org.apache.qpid.server.cluster.util.Bindings; -import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.protocol.AMQMethodEvent; import org.apache.qpid.server.protocol.AMQProtocolSession; -import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.state.StateAwareMethodListener; import org.apache.qpid.server.virtualhost.VirtualHost; @@ -48,8 +46,8 @@ public class ReplayStore implements ReplayManager, StateAwareMethodListener { private static final Logger _logger = Logger.getLogger(ReplayStore.class); - private final Map, MethodRecorder> _globalRecorders = new HashMap, MethodRecorder>(); - private final Map, MethodRecorder> _localRecorders = new HashMap, MethodRecorder>(); + private final Map, MethodRecorder> _globalRecorders = new HashMap, MethodRecorder>(); + private final Map, MethodRecorder> _localRecorders = new HashMap, MethodRecorder>(); private final Map _sharedQueues = new ConcurrentHashMap(); private final Map _privateQueues = new ConcurrentHashMap(); private final Bindings _sharedBindings = new Bindings(); @@ -80,7 +78,7 @@ public class ReplayStore implements ReplayManager, StateAwareMethodListener VirtualHost virtualHost = session.getVirtualHost(); _logger.debug(new LogMessage("Replay store received {0}", evt.getMethod())); - AMQMethodBody request = evt.getMethod(); + AMQMethodBodyImpl request = evt.getMethod(); //allow any (relevant) recorder registered for this type of request to record it: MethodRecorder recorder = getRecorders(session).get(request.getClass()); @@ -90,7 +88,7 @@ public class ReplayStore implements ReplayManager, StateAwareMethodListener } } - private Map, MethodRecorder> getRecorders(AMQProtocolSession session) + private Map, MethodRecorder> getRecorders(AMQProtocolSession session) { if (ClusteredProtocolSession.isPeerSession(session)) { @@ -102,9 +100,9 @@ public class ReplayStore implements ReplayManager, StateAwareMethodListener } } - public List replay(boolean isLeader) + public List replay(boolean isLeader) { - List methods = new ArrayList(); + List methods = new ArrayList(); methods.addAll(_exchanges.values()); methods.addAll(_privateQueues.values()); synchronized(_privateBindings) diff --git a/java/cluster/src/test/java/org/apache/qpid/server/cluster/BrokerTest.java b/java/cluster/src/test/java/org/apache/qpid/server/cluster/BrokerTest.java index f1da312eea..ad7d7e1b5f 100644 --- a/java/cluster/src/test/java/org/apache/qpid/server/cluster/BrokerTest.java +++ b/java/cluster/src/test/java/org/apache/qpid/server/cluster/BrokerTest.java @@ -23,11 +23,11 @@ package org.apache.qpid.server.cluster; import junit.framework.TestCase; import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQException; -import org.apache.qpid.framing.AMQBody; +import org.apache.qpid.framing.AMQBodyImpl; import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQFrameDecodingException; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.cluster.policy.StandardPolicies; import java.util.ArrayList; @@ -91,13 +91,13 @@ public class BrokerTest extends TestCase //simple send (no response) public void testSend_noResponse() throws AMQException { - AMQBody[] msgs = new AMQBody[]{ + AMQBodyImpl[] msgs = new AMQBodyImpl[]{ new TestMethod("A"), new TestMethod("B"), new TestMethod("C") }; RecordingBroker broker = new RecordingBroker("myhost", 1); - for (AMQBody msg : msgs) + for (AMQBodyImpl msg : msgs) { broker.send(new SimpleBodySendable(msg), null); } @@ -142,7 +142,7 @@ public class BrokerTest extends TestCase assertTrue(handler.failed()); } - private static class TestMethod extends AMQMethodBody + private static class TestMethod extends AMQMethodBodyImpl { private final Object id; @@ -209,19 +209,19 @@ public class BrokerTest extends TestCase private static class GroupResponseValidator implements GroupResponseHandler { - private final AMQMethodBody _response; + private final AMQMethodBodyImpl _response; private final List _members; private boolean _completed = false; - GroupResponseValidator(AMQMethodBody response, List members) + GroupResponseValidator(AMQMethodBodyImpl response, List members) { _response = response; _members = members; } - public void response(List responses, List members) + public void response(List responses, List members) { - for (AMQMethodBody r : responses) + for (AMQMethodBodyImpl r : responses) { assertEquals(_response, r); } diff --git a/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestBroker.java b/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestBroker.java index d3ccbf0ac6..7f513530e0 100644 --- a/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestBroker.java +++ b/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestBroker.java @@ -23,7 +23,7 @@ package org.apache.qpid.server.cluster; import org.apache.qpid.AMQException; import org.apache.qpid.framing.AMQDataBlock; import org.apache.qpid.framing.AMQFrame; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import java.io.IOException; @@ -39,16 +39,16 @@ class TestBroker extends Broker return true; } - void connectAsynch(Iterable msgs) + void connectAsynch(Iterable msgs) { replay(msgs); } - void replay(Iterable msgs) + void replay(Iterable msgs) { try { - for (AMQMethodBody b : msgs) + for (AMQMethodBodyImpl b : msgs) { send(new AMQFrame(0, b)); } diff --git a/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestReplayManager.java b/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestReplayManager.java index c529c83cc0..ba62e86101 100644 --- a/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestReplayManager.java +++ b/java/cluster/src/test/java/org/apache/qpid/server/cluster/TestReplayManager.java @@ -20,7 +20,7 @@ */ package org.apache.qpid.server.cluster; -import org.apache.qpid.framing.AMQMethodBody; +import org.apache.qpid.framing.AMQMethodBodyImpl; import org.apache.qpid.server.cluster.replay.ReplayManager; import java.util.ArrayList; @@ -28,19 +28,19 @@ import java.util.List; class TestReplayManager implements ReplayManager { - private final List _msgs; + private final List _msgs; TestReplayManager() { - this(new ArrayList()); + this(new ArrayList()); } - TestReplayManager(List msgs) + TestReplayManager(List msgs) { _msgs = msgs; } - public List replay(boolean isLeader) + public List replay(boolean isLeader) { return _msgs; } diff --git a/java/common/src/main/java/org/apache/qpid/AMQChannelException.java b/java/common/src/main/java/org/apache/qpid/AMQChannelException.java index d8c9b287bd..12120bd10d 100644 --- a/java/common/src/main/java/org/apache/qpid/AMQChannelException.java +++ b/java/common/src/main/java/org/apache/qpid/AMQChannelException.java @@ -23,6 +23,8 @@ package org.apache.qpid; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ChannelCloseBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionCloseBodyImpl; +import org.apache.qpid.framing.amqp_8_0.ChannelCloseBodyImpl; import org.apache.qpid.protocol.AMQConstant; public class AMQChannelException extends AMQException @@ -53,6 +55,6 @@ public class AMQChannelException extends AMQException public AMQFrame getCloseFrame(int channel) { - return ChannelCloseBody.createAMQFrame(channel, major, minor, _classId, _methodId, getErrorCode().getCode(), new AMQShortString(getMessage())); + return new AMQFrame(channel, new ChannelCloseBodyImpl(getErrorCode().getCode(), new AMQShortString(getMessage()),0,0)); } } diff --git a/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java b/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java index c4f80191a3..094e26802d 100644 --- a/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java +++ b/java/common/src/main/java/org/apache/qpid/AMQConnectionException.java @@ -24,6 +24,7 @@ package org.apache.qpid; import org.apache.qpid.framing.AMQFrame; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.ConnectionCloseBody; +import org.apache.qpid.framing.amqp_8_0.ConnectionCloseBodyImpl; import org.apache.qpid.protocol.AMQConstant; public class AMQConnectionException extends AMQException @@ -57,7 +58,7 @@ public class AMQConnectionException extends AMQException public AMQFrame getCloseFrame(int channel) { - return ConnectionCloseBody.createAMQFrame(channel, major, minor, _classId, _methodId, getErrorCode().getCode(), new AMQShortString(getMessage())); + return new AMQFrame(channel, new ConnectionCloseBodyImpl(getErrorCode().getCode(), new AMQShortString(getMessage()),_classId,_methodId)); } diff --git a/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java b/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java index bb981a242f..6e0a5c3786 100644 --- a/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java +++ b/java/common/src/main/java/org/apache/qpid/codec/AMQDecoder.java @@ -48,13 +48,21 @@ public class AMQDecoder extends CumulativeProtocolDecoder protected boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { - if (_expectProtocolInitiation) + try { - return doDecodePI(session, in, out); + if (_expectProtocolInitiation) + { + return doDecodePI(session, in, out); + } + else + { + return doDecodeDataBlock(session, in, out); + } } - else + catch (Exception e) { - return doDecodeDataBlock(session, in, out); + e.printStackTrace(); + throw e; } } diff --git a/java/common/src/main/java/org/apache/qpid/common/ClientProperties.java b/java/common/src/main/java/org/apache/qpid/common/ClientProperties.java index 07371b5182..1f1911aa35 100644 --- a/java/common/src/main/java/org/apache/qpid/common/ClientProperties.java +++ b/java/common/src/main/java/org/apache/qpid/common/ClientProperties.java @@ -20,10 +20,28 @@ */ package org.apache.qpid.common; +import org.apache.qpid.framing.AMQShortString; + public enum ClientProperties { + + instance, product, version, - platform + platform; + + + private final AMQShortString _name; + + private ClientProperties() + { + _name = new AMQShortString(toString()); + } + + public AMQShortString getName() + { + return _name; + } + } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java b/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java index ebeea8d2b4..4dd5ab7a9a 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQBody.java @@ -7,9 +7,9 @@ * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -22,18 +22,15 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public abstract class AMQBody +public interface AMQBody { - public abstract byte getFrameType(); - - /** + byte getFrameType(); + + /** * Get the size of the body * @return unsigned short */ - protected abstract int getSize(); - - protected abstract void writePayload(ByteBuffer buffer); - - protected abstract void populateFromBuffer(ByteBuffer buffer, long size) - throws AMQFrameDecodingException, AMQProtocolVersionException; + int getSize(); + + void writePayload(ByteBuffer buffer); } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQBodyImpl.java b/java/common/src/main/java/org/apache/qpid/framing/AMQBodyImpl.java new file mode 100644 index 0000000000..6b2d1feae5 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQBodyImpl.java @@ -0,0 +1,27 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.framing; + + +public abstract class AMQBodyImpl implements AMQBody +{ + +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java b/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java index 43f888c029..2ecd4d4650 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQDataBlockDecoder.java @@ -72,7 +72,7 @@ public class AMQDataBlockDecoder final byte type = in.get(); BodyFactory bodyFactory; - if(type == AMQMethodBody.TYPE) + if(type == AMQMethodBodyImpl.TYPE) { bodyFactory = (BodyFactory) session.getAttribute(SESSION_METHOD_BODY_FACTORY); if(bodyFactory == null) diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java index 111d9a8f20..d61c1c3d36 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBody.java @@ -1,132 +1,25 @@ -/* - * - * 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.framing; -import org.apache.mina.common.ByteBuffer; import org.apache.qpid.AMQChannelException; import org.apache.qpid.AMQConnectionException; import org.apache.qpid.protocol.AMQConstant; -public abstract class AMQMethodBody extends AMQBody +/** + * Created by IntelliJ IDEA. + * User: U146758 + * Date: 08-Mar-2007 + * Time: 11:30:28 + * To change this template use File | Settings | File Templates. + */ +public interface AMQMethodBody extends AMQBody { - public static final byte TYPE = 1; - - /** AMQP version */ - protected byte major; - protected byte minor; - - public byte getMajor() - { - return major; - } - - public byte getMinor() - { - return minor; - } - - public AMQMethodBody(byte major, byte minor) - { - this.major = major; - this.minor = minor; - } - - /** unsigned short */ - protected abstract int getBodySize(); - - /** @return unsigned short */ - protected abstract int getClazz(); - - /** @return unsigned short */ - protected abstract int getMethod(); - - protected abstract void writeMethodPayload(ByteBuffer buffer); - - public byte getFrameType() - { - return TYPE; - } - - protected int getSize() - { - return 2 + 2 + getBodySize(); - } - - protected void writePayload(ByteBuffer buffer) - { - EncodingUtils.writeUnsignedShort(buffer, getClazz()); - EncodingUtils.writeUnsignedShort(buffer, getMethod()); - writeMethodPayload(buffer); - } - - protected abstract void populateMethodBodyFromBuffer(ByteBuffer buffer) throws AMQFrameDecodingException; - - protected void populateFromBuffer(ByteBuffer buffer, long size) throws AMQFrameDecodingException - { - populateMethodBodyFromBuffer(buffer); - } - - public String toString() - { - StringBuffer buf = new StringBuffer(getClass().toString()); - buf.append(" Class: ").append(getClazz()); - buf.append(" Method: ").append(getMethod()); - return buf.toString(); - } - - /** - * Creates an AMQChannelException for the corresponding body type (a channel exception should include the class and - * method ids of the body it resulted from). - */ - - /** - * Convenience Method to create a channel not found exception - * - * @param channelId The channel id that is not found - * - * @return new AMQChannelException - */ - public AMQChannelException getChannelNotFoundException(int channelId) - { - return getChannelException(AMQConstant.NOT_FOUND, "Channel not found for id:" + channelId); - } - - public AMQChannelException getChannelException(AMQConstant code, String message) - { - return new AMQChannelException(code, message, getClazz(), getMethod(), major, minor); - } + AMQChannelException getChannelNotFoundException(int channelId); - public AMQChannelException getChannelException(AMQConstant code, String message, Throwable cause) - { - return new AMQChannelException(code, message, getClazz(), getMethod(), major, minor, cause); - } + AMQChannelException getChannelException(AMQConstant code, String message); - public AMQConnectionException getConnectionException(AMQConstant code, String message) - { - return new AMQConnectionException(code, message, getClazz(), getMethod(), major, minor); - } + AMQChannelException getChannelException(AMQConstant code, String message, Throwable cause); - public AMQConnectionException getConnectionException(AMQConstant code, String message, Throwable cause) - { - return new AMQConnectionException(code, message, getClazz(), getMethod(), major, minor, cause); - } + AMQConnectionException getConnectionException(AMQConstant code, String message); + AMQConnectionException getConnectionException(AMQConstant code, String message, Throwable cause); } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java index 5293c00379..f5cd971c0e 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyFactory.java @@ -37,6 +37,6 @@ public class AMQMethodBodyFactory implements BodyFactory public AMQBody createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException { - return _protocolSession.getRegistry().get((short)in.getUnsignedShort(), (short)in.getUnsignedShort(), in, bodySize); + return _protocolSession.getRegistry().convertToBody(in, bodySize); } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java new file mode 100644 index 0000000000..1951970a72 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyImpl.java @@ -0,0 +1,102 @@ +/* + * + * 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.framing; + +import org.apache.mina.common.ByteBuffer; +import org.apache.qpid.AMQChannelException; +import org.apache.qpid.AMQConnectionException; +import org.apache.qpid.protocol.AMQConstant; + +public abstract class AMQMethodBodyImpl extends AMQBodyImpl implements AMQMethodBody +{ + public static final byte TYPE = 1; + + + public abstract byte getMajor(); + public abstract byte getMinor(); + + /** unsigned short */ + protected abstract int getBodySize(); + + /** @return unsigned short */ + protected abstract int getClazz(); + + /** @return unsigned short */ + protected abstract int getMethod(); + + protected abstract void writeMethodPayload(ByteBuffer buffer); + + public byte getFrameType() + { + return TYPE; + } + + public int getSize() + { + return 2 + 2 + getBodySize(); + } + + public void writePayload(ByteBuffer buffer) + { + EncodingUtils.writeUnsignedShort(buffer, getClazz()); + EncodingUtils.writeUnsignedShort(buffer, getMethod()); + writeMethodPayload(buffer); + } + + + /** + * Creates an AMQChannelException for the corresponding body type (a channel exception should include the class and + * method ids of the body it resulted from). + */ + + /** + * Convenience Method to create a channel not found exception + * + * @param channelId The channel id that is not found + * + * @return new AMQChannelException + */ + public AMQChannelException getChannelNotFoundException(int channelId) + { + return getChannelException(AMQConstant.NOT_FOUND, "Channel not found for id:" + channelId); + } + + public AMQChannelException getChannelException(AMQConstant code, String message) + { + return new AMQChannelException(code, message, getClazz(), getMethod(), getMajor(), getMinor()); + } + + public AMQChannelException getChannelException(AMQConstant code, String message, Throwable cause) + { + return new AMQChannelException(code, message, getClazz(), getMethod(), getMajor(), getMinor(), cause); + } + + public AMQConnectionException getConnectionException(AMQConstant code, String message) + { + return new AMQConnectionException(code, message, getClazz(), getMethod(), getMajor(), getMinor()); + } + + public AMQConnectionException getConnectionException(AMQConstant code, String message, Throwable cause) + { + return new AMQConnectionException(code, message, getClazz(), getMethod(), getMajor(), getMinor(), cause); + } + +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java index cfbc9d1828..9a7868f3cd 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodBodyInstanceFactory.java @@ -5,6 +5,5 @@ import org.apache.mina.common.ByteBuffer; public abstract interface AMQMethodBodyInstanceFactory { - public AMQMethodBody newInstance(byte major, byte minor, ByteBuffer buffer, long size) throws AMQFrameDecodingException; - public AMQMethodBody newInstance(byte major, byte minor, int clazzID, int methodID, ByteBuffer buffer, long size) throws AMQFrameDecodingException; + public AMQMethodBody newInstance(ByteBuffer buffer, long size) throws AMQFrameDecodingException; } diff --git a/java/common/src/main/java/org/apache/qpid/framing/AMQMethodFactory.java b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodFactory.java new file mode 100644 index 0000000000..4ffc9e0066 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/AMQMethodFactory.java @@ -0,0 +1,90 @@ +/* + * + * 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.framing; + +import org.apache.mina.common.ByteBuffer; + + +public interface AMQMethodFactory +{ + + // Connection Methods + + ConnectionCloseBody createConnectionClose(); + + // Access Methods + + AccessRequestBody createAccessRequest(boolean active, boolean exclusive, boolean passive, boolean read, AMQShortString realm, boolean write); + + + // Tx Methods + + TxSelectBody createTxSelect(); + + TxCommitBody createTxCommit(); + + TxRollbackBody createTxRollback(); + + // Channel Methods + + ChannelOpenBody createChannelOpen(); + + ChannelCloseBody createChannelClose(int replyCode, AMQShortString replyText); + + ChannelFlowBody createChannelFlow(boolean active); + + + // Exchange Methods + + + ExchangeBoundBody createExchangeBound(AMQShortString exchangeName, + AMQShortString queueName, + AMQShortString routingKey); + + ExchangeDeclareBody createExchangeDeclare(AMQShortString name, AMQShortString type, int ticket); + + + // Queue Methods + + QueueDeclareBody createQueueDeclare(AMQShortString name, FieldTable arguments, boolean autoDelete, boolean durable, boolean exclusive, boolean passive, int ticket); + + QueueBindBody createQueueBind(AMQShortString queueName, AMQShortString exchangeName, AMQShortString routingKey, FieldTable arguments, int ticket); + + QueueDeleteBody createQueueDelete(AMQShortString queueName, boolean ifEmpty, boolean ifUnused, int ticket); + + + // Message Methods + + // In different versions of the protocol we change the class used for message transfer + // abstract this out so the appropriate methods are created + AMQMethodBody createRecover(boolean requeue); + + AMQMethodBody createConsumer(AMQShortString tag, AMQShortString queueName, FieldTable arguments, boolean noAck, boolean exclusive, boolean noLocal, int ticket); + + AMQMethodBody createConsumerCancel(AMQShortString consumerTag); + + AMQMethodBody createAcknowledge(long deliveryTag, boolean multiple); + + AMQMethodBody createRejectBody(long deliveryTag, boolean requeue); + + AMQMethodBody createMessageQos(int prefetchCount, int prefetchSize); + +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java index 1045b02868..8b784fa3f7 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java +++ b/java/common/src/main/java/org/apache/qpid/framing/BasicContentHeaderProperties.java @@ -24,7 +24,7 @@ import org.apache.log4j.Logger; import org.apache.mina.common.ByteBuffer; -public class BasicContentHeaderProperties implements ContentHeaderProperties +public class BasicContentHeaderProperties implements CommonContentHeaderProperties { private static final Logger _logger = Logger.getLogger(BasicContentHeaderProperties.class); @@ -421,14 +421,14 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties } } - public AMQShortString getContentTypeShortString() + public AMQShortString getContentType() { decodeContentTypeIfNecessary(); return _contentType; } - public String getContentType() + public String getContentTypeAsString() { decodeContentTypeIfNecessary(); return _contentType == null ? null : _contentType.toString(); @@ -444,15 +444,19 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties public void setContentType(String contentType) { - clearEncodedForm(); - _propertyFlags |= (1 << 15); - _contentType = contentType == null ? null : new AMQShortString(contentType); + setContentType(contentType == null ? null : new AMQShortString(contentType)); + } + + public String getEncodingAsString() + { + + return getEncoding() == null ? null : getEncoding().toString(); } - public String getEncoding() + public AMQShortString getEncoding() { decodeIfNecessary(); - return _encoding == null ? null : _encoding.toString(); + return _encoding; } public void setEncoding(String encoding) @@ -462,6 +466,14 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties _encoding = encoding == null ? null : new AMQShortString(encoding); } + public void setEncoding(AMQShortString encoding) + { + clearEncodedForm(); + _propertyFlags |= (1 << 14); + _encoding = encoding; + } + + public FieldTable getHeaders() { decodeHeadersIfNecessary(); @@ -508,26 +520,37 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties _priority = priority; } - public String getCorrelationId() + public AMQShortString getCorrelationId() + { + decodeIfNecessary(); + return _correlationId; + } + + public String getCorrelationIdAsString() { decodeIfNecessary(); return _correlationId == null ? null : _correlationId.toString(); } public void setCorrelationId(String correlationId) + { + setCorrelationId(correlationId == null ? null : new AMQShortString(correlationId)); + } + + public void setCorrelationId(AMQShortString correlationId) { clearEncodedForm(); _propertyFlags |= (1 << 10); - _correlationId = correlationId == null ? null : new AMQShortString(correlationId); + _correlationId = correlationId; } - public String getReplyTo() + public String getReplyToAsString() { decodeIfNecessary(); return _replyTo == null ? null : _replyTo.toString(); } - public AMQShortString getReplyToAsShortString() + public AMQShortString getReplyTo() { decodeIfNecessary(); return _replyTo; @@ -561,7 +584,13 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties } - public String getMessageId() + public AMQShortString getMessageId() + { + decodeIfNecessary(); + return _messageId; + } + + public String getMessageIdAsString() { decodeIfNecessary(); return _messageId == null ? null : _messageId.toString(); @@ -574,6 +603,14 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties _messageId = messageId == null ? null : new AMQShortString(messageId); } + public void setMessageId(AMQShortString messageId) + { + clearEncodedForm(); + _propertyFlags |= (1 << 7); + _messageId = messageId; + } + + public long getTimestamp() { decodeIfNecessary(); @@ -587,56 +624,102 @@ public class BasicContentHeaderProperties implements ContentHeaderProperties _timestamp = timestamp; } - public String getType() + public String getTypeAsString() { decodeIfNecessary(); return _type == null ? null : _type.toString(); } + + public AMQShortString getType() + { + decodeIfNecessary(); + return _type; + } + + public void setType(String type) + { + setType(type == null ? null : new AMQShortString(type)); + } + + public void setType(AMQShortString type) { clearEncodedForm(); _propertyFlags |= (1 << 5); - _type = type == null ? null : new AMQShortString(type); + _type = type; } - public String getUserId() + public String getUserIdAsString() { decodeIfNecessary(); return _userId == null ? null : _userId.toString(); } + public AMQShortString getUserId() + { + decodeIfNecessary(); + return _userId; + } + public void setUserId(String userId) + { + setUserId(userId == null ? null : new AMQShortString(userId)); + } + + public void setUserId(AMQShortString userId) { clearEncodedForm(); _propertyFlags |= (1 << 4); - _userId = userId == null ? null : new AMQShortString(userId); + _userId = userId; } - public String getAppId() + public String getAppIdAsString() { decodeIfNecessary(); return _appId == null ? null : _appId.toString(); } + public AMQShortString getAppId() + { + decodeIfNecessary(); + return _appId; + } + public void setAppId(String appId) + { + setAppId(appId == null ? null : new AMQShortString(appId)); + } + + public void setAppId(AMQShortString appId) { clearEncodedForm(); _propertyFlags |= (1 << 3); - _appId = appId == null ? null : new AMQShortString(appId); + _appId = appId; } - public String getClusterId() + public String getClusterIdAsString() { decodeIfNecessary(); return _clusterId == null ? null : _clusterId.toString(); } + public AMQShortString getClusterId() + { + decodeIfNecessary(); + return _clusterId; + } + public void setClusterId(String clusterId) + { + setClusterId(clusterId == null ? null : new AMQShortString(clusterId)); + } + + public void setClusterId(AMQShortString clusterId) { clearEncodedForm(); _propertyFlags |= (1 << 2); - _clusterId = clusterId == null ? null : new AMQShortString(clusterId); + _clusterId = clusterId; } public String toString() diff --git a/java/common/src/main/java/org/apache/qpid/framing/CommonContentHeaderProperties.java b/java/common/src/main/java/org/apache/qpid/framing/CommonContentHeaderProperties.java new file mode 100644 index 0000000000..1641cbf4e8 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/CommonContentHeaderProperties.java @@ -0,0 +1,65 @@ +package org.apache.qpid.framing; + +import org.apache.mina.common.ByteBuffer; + +import org.apache.log4j.Logger; + +public interface CommonContentHeaderProperties extends ContentHeaderProperties +{ + + AMQShortString getContentType(); + + void setContentType(AMQShortString contentType); + + FieldTable getHeaders(); + + void setHeaders(FieldTable headers); + + byte getDeliveryMode(); + + void setDeliveryMode(byte deliveryMode); + + byte getPriority(); + + void setPriority(byte priority); + + AMQShortString getCorrelationId(); + + void setCorrelationId(AMQShortString correlationId); + + AMQShortString getReplyTo(); + + void setReplyTo(AMQShortString replyTo); + + long getExpiration(); + + void setExpiration(long expiration); + + AMQShortString getMessageId(); + + void setMessageId(AMQShortString messageId); + + long getTimestamp(); + + void setTimestamp(long timestamp); + + AMQShortString getType(); + + void setType(AMQShortString type); + + AMQShortString getUserId(); + + void setUserId(AMQShortString userId); + + AMQShortString getAppId(); + + void setAppId(AMQShortString appId); + + AMQShortString getClusterId(); + + void setClusterId(AMQShortString clusterId); + + AMQShortString getEncoding(); + + void setEncoding(AMQShortString encoding); +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java b/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java index be38695384..a1aaab06c6 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentBody.java @@ -22,7 +22,7 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public class ContentBody extends AMQBody +public class ContentBody extends AMQBodyImpl { public static final byte TYPE = 3; diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java b/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java index 5636229d53..7b6a92e691 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentBodyFactory.java @@ -39,7 +39,7 @@ public class ContentBodyFactory implements BodyFactory _log.debug("Creating content body factory"); } - public AMQBody createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException + public AMQBodyImpl createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException { return new ContentBody(in, bodySize); } diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java index 02631a5f88..c71f47bad2 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBody.java @@ -22,7 +22,7 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public class ContentHeaderBody extends AMQBody +public class ContentHeaderBody extends AMQBodyImpl { public static final byte TYPE = 2; @@ -110,7 +110,7 @@ public class ContentHeaderBody extends AMQBody properties.writePropertyListPayload(buffer); } - public static AMQFrame createAMQFrame(int channelId, int classId, int weight, BasicContentHeaderProperties properties, + public static AMQFrame createAMQFrame(int channelId, int classId, int weight, CommonContentHeaderProperties properties, long bodySize) { return new AMQFrame(channelId, new ContentHeaderBody(classId, weight, properties, bodySize)); diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java index 818fc9cf0c..9570ec800d 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderBodyFactory.java @@ -39,7 +39,7 @@ public class ContentHeaderBodyFactory implements BodyFactory _log.debug("Creating content header body factory"); } - public AMQBody createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException + public AMQBodyImpl createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException { // all content headers are the same - it is only the properties that differ. // the content header body further delegates construction of properties diff --git a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java index 7dac018872..a8a8097fd2 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ContentHeaderPropertiesFactory.java @@ -20,6 +20,8 @@ */ package org.apache.qpid.framing; +import org.apache.qpid.framing.amqp_8_0.BasicConsumeBodyImpl; + import org.apache.mina.common.ByteBuffer; public class ContentHeaderPropertiesFactory @@ -43,7 +45,7 @@ public class ContentHeaderPropertiesFactory // AMQP version change: "Hardwired" version to major=8, minor=0 // TODO: Change so that the actual version is obtained from // the ProtocolInitiation object for this session. - if (classId == BasicConsumeBody.getClazz((byte)8, (byte)0)) + if (classId == BasicConsumeBodyImpl.CLASS_ID) { properties = new BasicContentHeaderProperties(); } diff --git a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java index 246e5ebc90..a7544c5747 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java +++ b/java/common/src/main/java/org/apache/qpid/framing/FieldTable.java @@ -41,10 +41,14 @@ public class FieldTable private LinkedHashMap _properties; private long _encodedSize; private static final int INITIAL_HASHMAP_CAPACITY = 16; + private static final int INITIAL_ENCODED_FORM_SIZE = 256; public FieldTable() { super(); +// _encodedForm = ByteBuffer.allocate(INITIAL_ENCODED_FORM_SIZE); +// _encodedForm.setAutoExpand(true); +// _encodedForm.limit(0); } /** @@ -109,11 +113,28 @@ public class FieldTable private AMQTypedValue setProperty(AMQShortString key, AMQTypedValue val) { initMapIfNecessary(); - _encodedForm = null; - if(val == null) + if(_properties.containsKey(key)) + { + _encodedForm = null; + + if(val == null) + { + return removeKey(key); + } + } + else if(_encodedForm != null && val != null) + { + EncodingUtils.writeShortStringBytes(_encodedForm, key); + val.writeToBuffer(_encodedForm); + + } + else if (val == null) { - return removeKey(key); + return null; } + + + AMQTypedValue oldVal = _properties.put(key,val); if(oldVal != null) { @@ -134,7 +155,7 @@ public class FieldTable { if(_properties == null) { - if(_encodedForm == null) + if(_encodedForm == null || _encodedSize == 0) { _properties = new LinkedHashMap(); } @@ -655,6 +676,7 @@ public class FieldTable if (trace) { _logger.trace("FieldTable::writeToBuffer: Writing encoded length of " + getEncodedSize() + "..."); + _logger.trace(_properties); } EncodingUtils.writeUnsignedInteger(buffer, getEncodedSize()); @@ -701,6 +723,7 @@ public class FieldTable public void addAll(FieldTable fieldTable) { initMapIfNecessary(); + _encodedForm = null; _properties.putAll(fieldTable._properties); recalculateEncodedSize(); } @@ -836,7 +859,13 @@ public class FieldTable if(_encodedForm != null) { - buffer.put(_encodedForm); + + if(_encodedForm.position() != 0) + { + _encodedForm.flip(); + } +// _encodedForm.limit((int)getEncodedSize()); + buffer.put(_encodedForm); } else if(_properties != null) { @@ -924,4 +953,33 @@ public class FieldTable } } + public int hashCode() + { + initMapIfNecessary(); + return _properties.hashCode(); + } + + + public boolean equals(Object o) + { + if(o == this) + { + return true; + } + if(o == null) + { + return false; + } + if(!(o instanceof FieldTable)) + { + return false; + } + + initMapIfNecessary(); + + FieldTable f = (FieldTable) o; + f.initMapIfNecessary(); + + return _properties.equals(f._properties); + } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java b/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java index 7246c4a1cf..17b2a2f9c2 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java +++ b/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBody.java @@ -22,7 +22,7 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -public class HeartbeatBody extends AMQBody +public class HeartbeatBody extends AMQBodyImpl { public static final byte TYPE = 8; public static AMQFrame FRAME = new HeartbeatBody().toFrame(); @@ -46,12 +46,12 @@ public class HeartbeatBody extends AMQBody return TYPE; } - protected int getSize() + public int getSize() { return 0;//heartbeats we generate have no payload } - protected void writePayload(ByteBuffer buffer) + public void writePayload(ByteBuffer buffer) { } diff --git a/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java b/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java index c7ada708dc..2249f1d1cf 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java +++ b/java/common/src/main/java/org/apache/qpid/framing/HeartbeatBodyFactory.java @@ -24,7 +24,7 @@ import org.apache.mina.common.ByteBuffer; public class HeartbeatBodyFactory implements BodyFactory { - public AMQBody createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException + public AMQBodyImpl createBody(ByteBuffer in, long bodySize) throws AMQFrameDecodingException { return new HeartbeatBody(); } diff --git a/java/common/src/main/java/org/apache/qpid/framing/MainRegistry.java b/java/common/src/main/java/org/apache/qpid/framing/MainRegistry.java new file mode 100644 index 0000000000..d75589f914 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpid/framing/MainRegistry.java @@ -0,0 +1,35 @@ +/* + * + * 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.framing; + +public class MainRegistry +{ + + public static VersionSpecificRegistry getVersionSpecificRegistry(byte versionMajor, byte versionMinor) + { + return null; //To change body of created methods use File | Settings | File Templates. + } + + public static VersionSpecificRegistry getVersionSpecificRegistry(ProtocolVersion pv) + { + return null; //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/java/common/src/main/java/org/apache/qpid/framing/MethodConverter_8_0.java b/java/common/src/main/java/org/apache/qpid/framing/MethodConverter_8_0.java index dd93cc97fa..f253372a65 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/MethodConverter_8_0.java +++ b/java/common/src/main/java/org/apache/qpid/framing/MethodConverter_8_0.java @@ -4,6 +4,7 @@ import org.apache.qpid.framing.abstraction.ProtocolVersionMethodConverter; import org.apache.qpid.framing.abstraction.ContentChunk; import org.apache.qpid.framing.abstraction.MessagePublishInfo; import org.apache.qpid.framing.abstraction.AbstractMethodConverter; +import org.apache.qpid.framing.amqp_8_0.BasicPublishBodyImpl; import org.apache.mina.common.ByteBuffer; @@ -19,7 +20,7 @@ public class MethodConverter_8_0 extends AbstractMethodConverter implements Prot } - public AMQBody convertToBody(ContentChunk contentChunk) + public AMQBodyImpl convertToBody(ContentChunk contentChunk) { return new ContentBody(contentChunk.getData()); } @@ -52,8 +53,8 @@ public class MethodConverter_8_0 extends AbstractMethodConverter implements Prot public void configure() { - _basicPublishClassId = BasicPublishBody.getClazz(getProtocolMajorVersion(),getProtocolMinorVersion()); - _basicPublishMethodId = BasicPublishBody.getMethod(getProtocolMajorVersion(),getProtocolMinorVersion()); + _basicPublishClassId = BasicPublishBodyImpl.CLASS_ID; + _basicPublishMethodId = BasicPublishBodyImpl.METHOD_ID; } @@ -87,18 +88,15 @@ public class MethodConverter_8_0 extends AbstractMethodConverter implements Prot } - public AMQMethodBody convertToBody(MessagePublishInfo info) + public AMQMethodBodyImpl convertToBody(MessagePublishInfo info) { - return new BasicPublishBody(getProtocolMajorVersion(), - getProtocolMinorVersion(), - _basicPublishClassId, - _basicPublishMethodId, - info.getExchange(), - info.isImmediate(), + return new BasicPublishBodyImpl(0, // ticket + info.getExchange(), + info.getRoutingKey(), info.isMandatory(), - info.getRoutingKey(), - 0) ; // ticket + info.isImmediate() + ) ; } } diff --git a/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java b/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java index 697a0f4249..8b40fe72eb 100644 --- a/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java +++ b/java/common/src/main/java/org/apache/qpid/framing/ProtocolInitiation.java @@ -25,25 +25,50 @@ import org.apache.mina.common.IoSession; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import org.apache.qpid.AMQException; +import java.io.UnsupportedEncodingException; + public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQDataBlock { - public char[] header = new char[]{'A','M','Q','P'}; + // TODO: generate these constants automatically from the xml protocol spec file + public static final byte[] AMQP_HEADER = new byte[]{(byte)'A',(byte)'M',(byte)'Q',(byte)'P'}; - private static byte CURRENT_PROTOCOL_CLASS = 1; - private static final int CURRENT_PROTOCOL_INSTANCE = 1; + private static final byte CURRENT_PROTOCOL_CLASS = 1; + private static final byte TCP_PROTOCOL_INSTANCE = 1; + + public final byte[] _protocolHeader; + public final byte _protocolClass; + public final byte _protocolInstance; + public final byte _protocolMajor; + public final byte _protocolMinor; - public byte protocolClass = CURRENT_PROTOCOL_CLASS; - public byte protocolInstance = CURRENT_PROTOCOL_INSTANCE; - public byte protocolMajor; - public byte protocolMinor; // public ProtocolInitiation() {} - public ProtocolInitiation(byte major, byte minor) + public ProtocolInitiation(byte[] protocolHeader, byte protocolClass, byte protocolInstance, byte protocolMajor, byte protocolMinor) + { + _protocolHeader = protocolHeader; + _protocolClass = protocolClass; + _protocolInstance = protocolInstance; + _protocolMajor = protocolMajor; + _protocolMinor = protocolMinor; + } + + public ProtocolInitiation(ProtocolVersion pv) { - protocolMajor = major; - protocolMinor = minor; + this(AMQP_HEADER, CURRENT_PROTOCOL_CLASS, TCP_PROTOCOL_INSTANCE, pv.getMajorVersion(), pv.getMinorVersion()); + } + + + public ProtocolInitiation(ByteBuffer in) + { + _protocolHeader = new byte[4]; + in.get(_protocolHeader); + + _protocolClass = in.get(); + _protocolInstance = in.get(); + _protocolMajor = in.get(); + _protocolMinor = in.get(); } public long getSize() @@ -53,19 +78,12 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData public void writePayload(ByteBuffer buffer) { - for (int i = 0; i < header.length; i++) - { - buffer.put((byte) header[i]); - } - buffer.put(protocolClass); - buffer.put(protocolInstance); - buffer.put(protocolMajor); - buffer.put(protocolMinor); - } - public void populateFromBuffer(ByteBuffer buffer) throws AMQException - { - throw new AMQException("Method not implemented"); + buffer.put(_protocolHeader); + buffer.put(_protocolClass); + buffer.put(_protocolInstance); + buffer.put(_protocolMajor); + buffer.put(_protocolMinor); } public boolean equals(Object o) @@ -76,36 +94,36 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData } ProtocolInitiation pi = (ProtocolInitiation) o; - if (pi.header == null) + if (pi._protocolHeader == null) { return false; } - if (header.length != pi.header.length) + if (_protocolHeader.length != pi._protocolHeader.length) { return false; } - for (int i = 0; i < header.length; i++) + for (int i = 0; i < _protocolHeader.length; i++) { - if (header[i] != pi.header[i]) + if (_protocolHeader[i] != pi._protocolHeader[i]) { return false; } } - return (protocolClass == pi.protocolClass && - protocolInstance == pi.protocolInstance && - protocolMajor == pi.protocolMajor && - protocolMinor == pi.protocolMinor); + return (_protocolClass == pi._protocolClass && + _protocolInstance == pi._protocolInstance && + _protocolMajor == pi._protocolMajor && + _protocolMinor == pi._protocolMinor); } public static class Decoder //implements MessageDecoder { /** * - * @param session - * @param in + * @param session the session + * @param in input buffer * @return true if we have enough data to decode the PI frame fully, false if more * data is required */ @@ -115,63 +133,62 @@ public class ProtocolInitiation extends AMQDataBlock implements EncodableAMQData } public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) - throws Exception { - byte[] theHeader = new byte[4]; - in.get(theHeader); - ProtocolInitiation pi = new ProtocolInitiation((byte)0, (byte)0); - pi.header = new char[]{(char) theHeader[0],(char) theHeader[CURRENT_PROTOCOL_INSTANCE],(char) theHeader[2], (char) theHeader[3]}; - String stringHeader = new String(pi.header); - if (!"AMQP".equals(stringHeader)) - { - throw new AMQProtocolHeaderException("Invalid protocol header - read " + stringHeader); - } - pi.protocolClass = in.get(); - pi.protocolInstance = in.get(); - pi.protocolMajor = in.get(); - pi.protocolMinor = in.get(); + ProtocolInitiation pi = new ProtocolInitiation(in); out.write(pi); } } - public void checkVersion(ProtocolVersionList pvl) throws AMQException + public void checkVersion() throws AMQException { - if (protocolClass != CURRENT_PROTOCOL_CLASS) - { - throw new AMQProtocolClassException("Protocol class " + CURRENT_PROTOCOL_CLASS + " was expected; received " + - protocolClass); - } - if (protocolInstance != CURRENT_PROTOCOL_INSTANCE) + + if(_protocolHeader.length != 4) { - throw new AMQProtocolInstanceException("Protocol instance " + CURRENT_PROTOCOL_INSTANCE + " was expected; received " + - protocolInstance); + throw new AMQProtocolHeaderException("Protocol header should have exactly four octets"); } - - /* Look through list of available protocol versions */ - boolean found = false; - for (int i=0; i boolean methodReceived(AMQMethodEvent evt) throws Exception; + boolean methodReceived(AMQMethodEvent evt) throws AMQException; /** * Callback when an error has occurred. Allows listeners to clean up. diff --git a/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java b/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java index b57c26e496..65f60e7f59 100644 --- a/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java +++ b/java/common/src/main/java/org/apache/qpid/protocol/AMQVersionAwareProtocolSession.java @@ -20,9 +20,9 @@ */ package org.apache.qpid.protocol; -import org.apache.qpid.framing.VersionSpecificRegistry; +import org.apache.qpid.framing.MethodRegistry; public interface AMQVersionAwareProtocolSession extends AMQProtocolWriter, ProtocolVersionAware { - public VersionSpecificRegistry getRegistry(); + public MethodRegistry getRegistry(); } diff --git a/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java b/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java index 64db953bc2..c2c0bf29b7 100644 --- a/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java +++ b/java/common/src/main/java/org/apache/qpid/protocol/ProtocolVersionAware.java @@ -20,9 +20,10 @@ */ package org.apache.qpid.protocol; +import org.apache.qpid.framing.ProtocolVersion; + public interface ProtocolVersionAware { - public byte getProtocolMinorVersion(); + public ProtocolVersion getProtocolVersion(); - public byte getProtocolMajorVersion(); } diff --git a/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java b/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java index 0f706ac553..4fd1f60d69 100644 --- a/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java +++ b/java/common/src/test/java/org/apache/qpid/framing/BasicContentHeaderPropertiesTest.java @@ -22,8 +22,6 @@ package org.apache.qpid.framing; import org.apache.mina.common.ByteBuffer; -import java.util.HashMap; - import junit.framework.TestCase; @@ -94,14 +92,14 @@ public class BasicContentHeaderPropertiesTest extends TestCase { String contentType = "contentType"; _testProperties.setContentType(contentType); - assertEquals(contentType, _testProperties.getContentType()); + assertEquals(contentType, _testProperties.getContentTypeAsString()); } public void testSetGetEncoding() { String encoding = "encoding"; _testProperties.setEncoding(encoding); - assertEquals(encoding, _testProperties.getEncoding()); + assertEquals(encoding, _testProperties.getEncodingAsString()); } public void testSetGetHeaders() @@ -128,14 +126,14 @@ public class BasicContentHeaderPropertiesTest extends TestCase { String correlationId = "correlationId"; _testProperties.setCorrelationId(correlationId); - assertEquals(correlationId, _testProperties.getCorrelationId()); + assertEquals(correlationId, _testProperties.getCorrelationIdAsString()); } public void testSetGetReplyTo() { String replyTo = "replyTo"; _testProperties.setReplyTo(replyTo); - assertEquals(replyTo, _testProperties.getReplyTo()); + assertEquals(replyTo, _testProperties.getReplyToAsString()); } public void testSetGetExpiration() @@ -149,7 +147,7 @@ public class BasicContentHeaderPropertiesTest extends TestCase { String messageId = "messageId"; _testProperties.setMessageId(messageId); - assertEquals(messageId, _testProperties.getMessageId()); + assertEquals(messageId, _testProperties.getMessageIdAsString()); } public void testSetGetTimestamp() @@ -163,28 +161,28 @@ public class BasicContentHeaderPropertiesTest extends TestCase { String type = "type"; _testProperties.setType(type); - assertEquals(type, _testProperties.getType()); + assertEquals(type, _testProperties.getTypeAsString()); } public void testSetGetUserId() { String userId = "userId"; _testProperties.setUserId(userId); - assertEquals(userId, _testProperties.getUserId()); + assertEquals(userId, _testProperties.getUserIdAsString()); } public void testSetGetAppId() { String appId = "appId"; _testProperties.setAppId(appId); - assertEquals(appId, _testProperties.getAppId()); + assertEquals(appId, _testProperties.getAppIdAsString()); } public void testSetGetClusterId() { String clusterId = "clusterId"; _testProperties.setClusterId(clusterId); - assertEquals(clusterId, _testProperties.getClusterId()); + assertEquals(clusterId, _testProperties.getClusterIdAsString()); } } diff --git a/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java b/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java index bab7954d11..c334547b7f 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java +++ b/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java @@ -26,6 +26,7 @@ import org.apache.qpid.framing.FieldTable; import org.apache.qpid.framing.AMQShortString; import org.apache.qpid.framing.VersionSpecificRegistry; import org.apache.qpid.server.AMQChannel; +import org.apache.qpid.server.output.ProtocolOutputConverter; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.protocol.AMQProtocolSession; import org.apache.qpid.server.store.MessageStore; @@ -170,6 +171,11 @@ public class MockProtocolSession implements AMQProtocolSession //To change body of implemented methods use File | Settings | File Templates. } + public ProtocolOutputConverter getProtocolOutputConverter() + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + public byte getProtocolMajorVersion() { return 8; //To change body of implemented methods use File | Settings | File Templates. -- cgit v1.2.1