From 633c33f224f3196f3f9bd80bd2e418d8143fea06 Mon Sep 17 00:00:00 2001 From: Kim van der Riet Date: Fri, 4 May 2012 15:39:19 +0000 Subject: QPID-3858: Updated branch - merged from trunk r.1333987 git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/asyncstore@1334037 13f79535-47bb-0310-9956-ffa450edef68 --- java/.gitignore | 2 + java/amqp-1-0-client-jms/build.xml | 29 + .../apache/qpid/amqp_1_0/jms/example/Hello.java | 178 + .../qpid/amqp_1_0/jms/example/hello.properties | 28 + .../org/apache/qpid/amqp_1_0/jms/AmqpMessage.java | 32 + .../org/apache/qpid/amqp_1_0/jms/BytesMessage.java | 26 + .../org/apache/qpid/amqp_1_0/jms/Connection.java | 37 + .../qpid/amqp_1_0/jms/ConnectionFactory.java | 31 + .../qpid/amqp_1_0/jms/ConnectionMetaData.java | 28 + .../org/apache/qpid/amqp_1_0/jms/Destination.java | 28 + .../apache/qpid/amqp_1_0/jms/JavaSerializable.java | 24 + .../org/apache/qpid/amqp_1_0/jms/MapMessage.java | 37 + .../java/org/apache/qpid/amqp_1_0/jms/Message.java | 178 + .../apache/qpid/amqp_1_0/jms/MessageConsumer.java | 36 + .../apache/qpid/amqp_1_0/jms/MessageProducer.java | 27 + .../apache/qpid/amqp_1_0/jms/ObjectMessage.java | 27 + .../java/org/apache/qpid/amqp_1_0/jms/Queue.java | 26 + .../org/apache/qpid/amqp_1_0/jms/QueueBrowser.java | 30 + .../apache/qpid/amqp_1_0/jms/QueueConnection.java | 30 + .../apache/qpid/amqp_1_0/jms/QueueReceiver.java | 29 + .../org/apache/qpid/amqp_1_0/jms/QueueSender.java | 29 + .../org/apache/qpid/amqp_1_0/jms/QueueSession.java | 42 + .../java/org/apache/qpid/amqp_1_0/jms/Session.java | 75 + .../apache/qpid/amqp_1_0/jms/StreamMessage.java | 26 + .../qpid/amqp_1_0/jms/TemporaryDestination.java | 33 + .../apache/qpid/amqp_1_0/jms/TemporaryQueue.java | 26 + .../apache/qpid/amqp_1_0/jms/TemporaryTopic.java | 26 + .../org/apache/qpid/amqp_1_0/jms/TextMessage.java | 26 + .../java/org/apache/qpid/amqp_1_0/jms/Topic.java | 26 + .../apache/qpid/amqp_1_0/jms/TopicConnection.java | 30 + .../apache/qpid/amqp_1_0/jms/TopicPublisher.java | 26 + .../org/apache/qpid/amqp_1_0/jms/TopicSession.java | 43 + .../apache/qpid/amqp_1_0/jms/TopicSubscriber.java | 29 + .../qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java | 78 + .../qpid/amqp_1_0/jms/impl/BytesMessageImpl.java | 538 + .../amqp_1_0/jms/impl/ConnectionFactoryImpl.java | 173 + .../qpid/amqp_1_0/jms/impl/ConnectionImpl.java | 329 + .../amqp_1_0/jms/impl/ConnectionMetaDataImpl.java | 105 + .../qpid/amqp_1_0/jms/impl/DestinationImpl.java | 85 + .../qpid/amqp_1_0/jms/impl/MapMessageImpl.java | 444 + .../amqp_1_0/jms/impl/MessageConsumerImpl.java | 447 + .../qpid/amqp_1_0/jms/impl/MessageFactory.java | 191 + .../apache/qpid/amqp_1_0/jms/impl/MessageImpl.java | 1209 ++ .../amqp_1_0/jms/impl/MessageProducerImpl.java | 362 + .../qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java | 143 + .../qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java | 138 + .../amqp_1_0/jms/impl/QueueConnectionImpl.java | 48 + .../apache/qpid/amqp_1_0/jms/impl/QueueImpl.java | 56 + .../qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java | 57 + .../qpid/amqp_1_0/jms/impl/QueueSenderImpl.java | 36 + .../qpid/amqp_1_0/jms/impl/QueueSessionImpl.java | 56 + .../apache/qpid/amqp_1_0/jms/impl/SessionImpl.java | 898 + .../qpid/amqp_1_0/jms/impl/StreamMessageImpl.java | 466 + .../qpid/amqp_1_0/jms/impl/TemporaryQueueImpl.java | 105 + .../qpid/amqp_1_0/jms/impl/TemporaryTopicImpl.java | 110 + .../qpid/amqp_1_0/jms/impl/TextMessageImpl.java | 93 + .../amqp_1_0/jms/impl/TopicConnectionImpl.java | 48 + .../apache/qpid/amqp_1_0/jms/impl/TopicImpl.java | 56 + .../qpid/amqp_1_0/jms/impl/TopicPublisherImpl.java | 36 + .../qpid/amqp_1_0/jms/impl/TopicSessionImpl.java | 55 + .../amqp_1_0/jms/impl/TopicSubscriberImpl.java | 133 + .../qpid/amqp_1_0/jms/jndi/NameParserImpl.java | 37 + .../jndi/PropertiesFileInitialContextFactory.java | 230 + .../qpid/amqp_1_0/jms/jndi/ReadOnlyContext.java | 527 + java/amqp-1-0-client/build.xml | 29 + .../qpid/amqp_1_0/client/AcknowledgeMode.java | 28 + .../org/apache/qpid/amqp_1_0/client/Command.java | 43 + .../apache/qpid/amqp_1_0/client/Connection.java | 481 + .../java/org/apache/qpid/amqp_1_0/client/Demo.java | 407 + .../java/org/apache/qpid/amqp_1_0/client/Dump.java | 116 + .../apache/qpid/amqp_1_0/client/Filereceiver.java | 327 + .../apache/qpid/amqp_1_0/client/Filesender.java | 276 + .../org/apache/qpid/amqp_1_0/client/Message.java | 148 + .../org/apache/qpid/amqp_1_0/client/ReadBytes.java | 77 + .../org/apache/qpid/amqp_1_0/client/Receive.java | 246 + .../org/apache/qpid/amqp_1_0/client/Receiver.java | 561 + .../org/apache/qpid/amqp_1_0/client/Request.java | 249 + .../org/apache/qpid/amqp_1_0/client/Respond.java | 347 + .../java/org/apache/qpid/amqp_1_0/client/Send.java | 244 + .../org/apache/qpid/amqp_1_0/client/SendBytes.java | 331 + .../org/apache/qpid/amqp_1_0/client/Sender.java | 392 + .../org/apache/qpid/amqp_1_0/client/Session.java | 354 + .../apache/qpid/amqp_1_0/client/Transaction.java | 49 + .../amqp_1_0/client/TransactionController.java | 194 + .../java/org/apache/qpid/amqp_1_0/client/Util.java | 529 + java/amqp-1-0-common/build.xml | 27 + .../codec/AbstractDescribedTypeWriter.java | 188 + .../qpid/amqp_1_0/codec/AbstractListWriter.java | 41 + .../qpid/amqp_1_0/codec/AbstractMapWriter.java | 95 + .../qpid/amqp_1_0/codec/ArrayTypeConstructor.java | 113 + .../apache/qpid/amqp_1_0/codec/ArrayWriter.java | 82 + .../apache/qpid/amqp_1_0/codec/BinaryString.java | 68 + .../qpid/amqp_1_0/codec/BinaryTypeConstructor.java | 80 + .../apache/qpid/amqp_1_0/codec/BinaryWriter.java | 75 + .../qpid/amqp_1_0/codec/BooleanConstructor.java | 80 + .../apache/qpid/amqp_1_0/codec/BooleanWriter.java | 70 + .../qpid/amqp_1_0/codec/ByteArrayWriter.java | 66 + .../qpid/amqp_1_0/codec/ByteBufferWriter.java | 75 + .../qpid/amqp_1_0/codec/ByteTypeConstructor.java | 59 + .../org/apache/qpid/amqp_1_0/codec/ByteWriter.java | 90 + .../qpid/amqp_1_0/codec/CharTypeConstructor.java | 67 + .../org/apache/qpid/amqp_1_0/codec/CharWriter.java | 53 + .../qpid/amqp_1_0/codec/CompoundTypeAssembler.java | 36 + .../amqp_1_0/codec/CompoundTypeConstructor.java | 192 + .../apache/qpid/amqp_1_0/codec/CompoundWriter.java | 420 + .../qpid/amqp_1_0/codec/DecimalConstructor.java | 230 + .../codec/DefaultDescribedTypeConstructor.java | 70 + .../qpid/amqp_1_0/codec/DelegatingValueWriter.java | 52 + .../apache/qpid/amqp_1_0/codec/DescribedType.java | 85 + .../amqp_1_0/codec/DescribedTypeConstructor.java | 41 + .../codec/DescribedTypeConstructorRegistry.java | 35 + .../qpid/amqp_1_0/codec/DoubleTypeConstructor.java | 58 + .../apache/qpid/amqp_1_0/codec/DoubleWriter.java | 54 + .../org/apache/qpid/amqp_1_0/codec/Encoder.java | 85 + .../qpid/amqp_1_0/codec/FixedEightWriter.java | 108 + .../qpid/amqp_1_0/codec/FixedFourWriter.java | 122 + .../apache/qpid/amqp_1_0/codec/FixedOneWriter.java | 79 + .../qpid/amqp_1_0/codec/FixedSixteenWriter.java | 150 + .../apache/qpid/amqp_1_0/codec/FixedTwoWriter.java | 96 + .../qpid/amqp_1_0/codec/FloatTypeConstructor.java | 58 + .../apache/qpid/amqp_1_0/codec/FloatWriter.java | 54 + .../apache/qpid/amqp_1_0/codec/FrameWriter.java | 245 + .../qpid/amqp_1_0/codec/IntTypeConstructor.java | 58 + .../apache/qpid/amqp_1_0/codec/IntegerWriter.java | 106 + .../org/apache/qpid/amqp_1_0/codec/ListWriter.java | 172 + .../qpid/amqp_1_0/codec/LongTypeConstructor.java | 58 + .../org/apache/qpid/amqp_1_0/codec/LongWriter.java | 111 + .../org/apache/qpid/amqp_1_0/codec/MapWriter.java | 102 + .../qpid/amqp_1_0/codec/NullTypeConstructor.java | 44 + .../org/apache/qpid/amqp_1_0/codec/NullWriter.java | 70 + .../qpid/amqp_1_0/codec/ProtocolHandler.java | 30 + .../qpid/amqp_1_0/codec/ProtocolHeaderHandler.java | 146 + .../amqp_1_0/codec/RestrictedTypeValueWriter.java | 55 + .../qpid/amqp_1_0/codec/ShortTypeConstructor.java | 58 + .../apache/qpid/amqp_1_0/codec/ShortWriter.java | 55 + .../amqp_1_0/codec/SimpleVariableWidthWriter.java | 68 + .../qpid/amqp_1_0/codec/SmallIntConstructor.java | 58 + .../qpid/amqp_1_0/codec/SmallLongConstructor.java | 58 + .../qpid/amqp_1_0/codec/SmallUIntConstructor.java | 58 + .../qpid/amqp_1_0/codec/SmallULongConstructor.java | 59 + .../qpid/amqp_1_0/codec/StringTypeConstructor.java | 132 + .../apache/qpid/amqp_1_0/codec/StringWriter.java | 146 + .../qpid/amqp_1_0/codec/SymbolArrayWriter.java | 170 + .../qpid/amqp_1_0/codec/SymbolTypeConstructor.java | 109 + .../apache/qpid/amqp_1_0/codec/SymbolWriter.java | 102 + .../amqp_1_0/codec/TimestampTypeConstructor.java | 60 + .../qpid/amqp_1_0/codec/TimestampWriter.java | 57 + .../qpid/amqp_1_0/codec/TypeConstructor.java | 32 + .../qpid/amqp_1_0/codec/UByteTypeConstructor.java | 59 + .../qpid/amqp_1_0/codec/UIntTypeConstructor.java | 59 + .../qpid/amqp_1_0/codec/ULongTypeConstructor.java | 61 + .../qpid/amqp_1_0/codec/UShortTypeConstructor.java | 60 + .../qpid/amqp_1_0/codec/UUIDTypeConstructor.java | 62 + .../org/apache/qpid/amqp_1_0/codec/UUIDWriter.java | 63 + .../qpid/amqp_1_0/codec/UnsignedByteWriter.java | 92 + .../qpid/amqp_1_0/codec/UnsignedIntegerWriter.java | 148 + .../qpid/amqp_1_0/codec/UnsignedLongWriter.java | 152 + .../qpid/amqp_1_0/codec/UnsignedShortWriter.java | 56 + .../apache/qpid/amqp_1_0/codec/ValueHandler.java | 159 + .../codec/ValueProducingProtocolHandler.java | 31 + .../apache/qpid/amqp_1_0/codec/ValueWriter.java | 58 + .../codec/VariableWidthTypeConstructor.java | 48 + .../qpid/amqp_1_0/codec/VariableWidthWriter.java | 169 + .../amqp_1_0/codec/WrapperTypeValueWriter.java | 55 + .../qpid/amqp_1_0/codec/ZeroListConstructor.java | 46 + .../qpid/amqp_1_0/codec/ZeroUIntConstructor.java | 45 + .../qpid/amqp_1_0/codec/ZeroULongConstructor.java | 45 + .../org/apache/qpid/amqp_1_0/framing/AMQFrame.java | 68 + .../framing/AMQPProtocolHeaderHandler.java | 85 + .../qpid/amqp_1_0/framing/ConnectionHandler.java | 559 + .../apache/qpid/amqp_1_0/framing/FrameHandler.java | 329 + .../qpid/amqp_1_0/framing/FrameParsingError.java | 34 + .../qpid/amqp_1_0/framing/FrameTypeHandler.java | 31 + .../amqp_1_0/framing/OversizeFrameException.java | 42 + .../apache/qpid/amqp_1_0/framing/SASLFrame.java | 42 + .../qpid/amqp_1_0/framing/SASLFrameHandler.java | 311 + .../framing/SASLProtocolHeaderHandler.java | 86 + .../qpid/amqp_1_0/framing/TransportFrame.java | 51 + .../qpid/amqp_1_0/messaging/MessageAttributes.java | 27 + .../qpid/amqp_1_0/messaging/SectionDecoder.java | 35 + .../amqp_1_0/messaging/SectionDecoderImpl.java | 62 + .../qpid/amqp_1_0/messaging/SectionEncoder.java | 34 + .../amqp_1_0/messaging/SectionEncoderImpl.java | 111 + .../amqp_1_0/transport/AMQPFrameTransport.java | 179 + .../qpid/amqp_1_0/transport/AMQPTransport.java | 170 + .../qpid/amqp_1_0/transport/BytesProcessor.java | 27 + .../qpid/amqp_1_0/transport/BytesTransport.java | 38 + .../amqp_1_0/transport/CallbackHandlerSource.java | 28 + .../amqp_1_0/transport/CircularBytesBuffer.java | 174 + .../amqp_1_0/transport/ConnectionEndpoint.java | 934 ++ .../transport/ConnectionEventListener.java | 43 + .../qpid/amqp_1_0/transport/ConnectionState.java | 31 + .../apache/qpid/amqp_1_0/transport/Container.java | 79 + .../apache/qpid/amqp_1_0/transport/Delivery.java | 95 + .../amqp_1_0/transport/DeliveryStateHandler.java | 28 + .../qpid/amqp_1_0/transport/ErrorHandler.java | 9 + .../amqp_1_0/transport/FrameOutputHandler.java | 36 + .../qpid/amqp_1_0/transport/FrameTransport.java | 37 + .../qpid/amqp_1_0/transport/LinkEndpoint.java | 542 + .../qpid/amqp_1_0/transport/LinkEventListener.java | 31 + .../org/apache/qpid/amqp_1_0/transport/Node.java | 26 + .../transport/ProtocolHeaderTransport.java | 134 + .../amqp_1_0/transport/ReceivingLinkEndpoint.java | 438 + .../amqp_1_0/transport/ReceivingLinkListener.java | 43 + .../transport/ReceivingSessionHalfEndpoint.java | 26 + .../qpid/amqp_1_0/transport/SASLEndpoint.java | 39 + .../qpid/amqp_1_0/transport/SASLEndpointImpl.java | 291 + .../amqp_1_0/transport/SASLFrameTransport.java | 78 + .../qpid/amqp_1_0/transport/SASLTransport.java | 85 + .../amqp_1_0/transport/SendingLinkEndpoint.java | 214 + .../amqp_1_0/transport/SendingLinkListener.java | 43 + .../transport/SendingSessionHalfEndpoint.java | 26 + .../qpid/amqp_1_0/transport/SequenceNumber.java | 110 + .../qpid/amqp_1_0/transport/SessionAttachment.java | 92 + .../qpid/amqp_1_0/transport/SessionEndpoint.java | 781 + .../amqp_1_0/transport/SessionEventListener.java | 47 + .../amqp_1_0/transport/SessionHalfEndpoint.java | 26 + .../qpid/amqp_1_0/transport/SessionState.java | 34 + .../amqp_1_0/transport/StateChangeListener.java | 25 + .../qpid/amqp_1_0/transport/UnsettledTransfer.java | 53 + .../qpid/amqp_1_0/type/AmqpErrorException.java | 54 + .../java/org/apache/qpid/amqp_1_0/type/Binary.java | 161 + .../apache/qpid/amqp_1_0/type/DeliveryState.java | 26 + .../qpid/amqp_1_0/type/DistributionMode.java | 26 + .../apache/qpid/amqp_1_0/type/ErrorCondition.java | 26 + .../org/apache/qpid/amqp_1_0/type/FrameBody.java | 29 + .../org/apache/qpid/amqp_1_0/type/GlobalTxId.java | 26 + .../apache/qpid/amqp_1_0/type/LifetimePolicy.java | 26 + .../org/apache/qpid/amqp_1_0/type/Outcome.java | 26 + .../apache/qpid/amqp_1_0/type/RestrictedType.java | 26 + .../apache/qpid/amqp_1_0/type/SaslFrameBody.java | 27 + .../org/apache/qpid/amqp_1_0/type/Section.java | 27 + .../java/org/apache/qpid/amqp_1_0/type/Source.java | 26 + .../java/org/apache/qpid/amqp_1_0/type/Symbol.java | 90 + .../java/org/apache/qpid/amqp_1_0/type/Target.java | 26 + .../apache/qpid/amqp_1_0/type/TxnCapability.java | 26 + .../java/org/apache/qpid/amqp_1_0/type/TxnId.java | 23 + .../apache/qpid/amqp_1_0/type/UnsignedByte.java | 134 + .../apache/qpid/amqp_1_0/type/UnsignedInteger.java | 149 + .../apache/qpid/amqp_1_0/type/UnsignedLong.java | 162 + .../apache/qpid/amqp_1_0/type/UnsignedShort.java | 132 + .../org/apache/qpid/amqp_1_0/type/WrapperType.java | 27 + .../type/codec/AMQPDescribedTypeRegistry.java | 389 + .../qpid/amqp_1_0/type/messaging/Accepted.java | 46 + .../qpid/amqp_1_0/type/messaging/AmqpSequence.java | 70 + .../qpid/amqp_1_0/type/messaging/AmqpValue.java | 66 + .../type/messaging/ApplicationProperties.java | 64 + .../apache/qpid/amqp_1_0/type/messaging/Data.java | 68 + .../amqp_1_0/type/messaging/DeleteOnClose.java | 46 + .../amqp_1_0/type/messaging/DeleteOnNoLinks.java | 46 + .../type/messaging/DeleteOnNoLinksOrMessages.java | 46 + .../type/messaging/DeleteOnNoMessages.java | 46 + .../type/messaging/DeliveryAnnotations.java | 64 + .../type/messaging/ExactSubjectFilter.java | 82 + .../qpid/amqp_1_0/type/messaging/Filter.java | 28 + .../qpid/amqp_1_0/type/messaging/Footer.java | 70 + .../qpid/amqp_1_0/type/messaging/Header.java | 161 + .../amqp_1_0/type/messaging/JMSSelectorFilter.java | 77 + .../type/messaging/MatchingSubjectFilter.java | 81 + .../type/messaging/MessageAnnotations.java | 64 + .../qpid/amqp_1_0/type/messaging/Modified.java | 112 + .../amqp_1_0/type/messaging/NoLocalFilter.java | 45 + .../qpid/amqp_1_0/type/messaging/Properties.java | 333 + .../qpid/amqp_1_0/type/messaging/Received.java | 88 + .../qpid/amqp_1_0/type/messaging/Rejected.java | 70 + .../qpid/amqp_1_0/type/messaging/Released.java | 46 + .../qpid/amqp_1_0/type/messaging/Source.java | 280 + .../qpid/amqp_1_0/type/messaging/StdDistMode.java | 95 + .../qpid/amqp_1_0/type/messaging/Target.java | 196 + .../type/messaging/TerminusDurability.java | 107 + .../type/messaging/TerminusExpiryPolicy.java | 119 + .../type/messaging/codec/AcceptedConstructor.java | 72 + .../type/messaging/codec/AcceptedWriter.java | 151 + .../messaging/codec/AmqpSequenceConstructor.java | 68 + .../type/messaging/codec/AmqpSequenceWriter.java | 80 + .../type/messaging/codec/AmqpValueConstructor.java | 65 + .../type/messaging/codec/AmqpValueWriter.java | 80 + .../codec/ApplicationPropertiesConstructor.java | 68 + .../codec/ApplicationPropertiesWriter.java | 80 + .../type/messaging/codec/DataConstructor.java | 65 + .../amqp_1_0/type/messaging/codec/DataWriter.java | 80 + .../messaging/codec/DeleteOnCloseConstructor.java | 72 + .../type/messaging/codec/DeleteOnCloseWriter.java | 142 + .../codec/DeleteOnNoLinksConstructor.java | 72 + .../DeleteOnNoLinksOrMessagesConstructor.java | 72 + .../codec/DeleteOnNoLinksOrMessagesWriter.java | 142 + .../messaging/codec/DeleteOnNoLinksWriter.java | 142 + .../codec/DeleteOnNoMessagesConstructor.java | 72 + .../messaging/codec/DeleteOnNoMessagesWriter.java | 142 + .../codec/DeliveryAnnotationsConstructor.java | 68 + .../messaging/codec/DeliveryAnnotationsWriter.java | 80 + .../codec/ExactSubjectFilterConstructor.java | 64 + .../messaging/codec/ExactSubjectFilterWriter.java | 78 + .../type/messaging/codec/FooterConstructor.java | 68 + .../type/messaging/codec/FooterWriter.java | 80 + .../type/messaging/codec/HeaderConstructor.java | 207 + .../type/messaging/codec/HeaderWriter.java | 182 + .../codec/JMSSelectorFilterConstructor.java | 66 + .../messaging/codec/JMSSelectorFilterWriter.java | 79 + .../codec/MatchingSubjectFilterConstructor.java | 65 + .../codec/MatchingSubjectFilterWriter.java | 79 + .../codec/MessageAnnotationsConstructor.java | 68 + .../messaging/codec/MessageAnnotationsWriter.java | 80 + .../type/messaging/codec/ModifiedConstructor.java | 154 + .../type/messaging/codec/ModifiedWriter.java | 166 + .../messaging/codec/NoLocalFilterConstructor.java | 56 + .../type/messaging/codec/NoLocalFilterWriter.java | 89 + .../messaging/codec/PropertiesConstructor.java | 424 + .../type/messaging/codec/PropertiesWriter.java | 246 + .../type/messaging/codec/ReceivedConstructor.java | 126 + .../type/messaging/codec/ReceivedWriter.java | 158 + .../type/messaging/codec/RejectedConstructor.java | 99 + .../type/messaging/codec/RejectedWriter.java | 150 + .../type/messaging/codec/ReleasedConstructor.java | 72 + .../type/messaging/codec/ReleasedWriter.java | 142 + .../type/messaging/codec/SourceConstructor.java | 384 + .../type/messaging/codec/SourceWriter.java | 230 + .../type/messaging/codec/TargetConstructor.java | 269 + .../type/messaging/codec/TargetWriter.java | 198 + .../qpid/amqp_1_0/type/security/SaslChallenge.java | 74 + .../qpid/amqp_1_0/type/security/SaslCode.java | 131 + .../qpid/amqp_1_0/type/security/SaslInit.java | 116 + .../amqp_1_0/type/security/SaslMechanisms.java | 74 + .../qpid/amqp_1_0/type/security/SaslOutcome.java | 95 + .../qpid/amqp_1_0/type/security/SaslResponse.java | 74 + .../security/codec/SaslChallengeConstructor.java | 99 + .../type/security/codec/SaslChallengeWriter.java | 150 + .../type/security/codec/SaslInitConstructor.java | 153 + .../type/security/codec/SaslInitWriter.java | 166 + .../security/codec/SaslMechanismsConstructor.java | 106 + .../type/security/codec/SaslMechanismsWriter.java | 150 + .../security/codec/SaslOutcomeConstructor.java | 126 + .../type/security/codec/SaslOutcomeWriter.java | 158 + .../security/codec/SaslResponseConstructor.java | 99 + .../type/security/codec/SaslResponseWriter.java | 150 + .../amqp_1_0/type/transaction/Coordinator.java | 70 + .../qpid/amqp_1_0/type/transaction/Declare.java | 66 + .../qpid/amqp_1_0/type/transaction/Declared.java | 67 + .../qpid/amqp_1_0/type/transaction/Discharge.java | 87 + .../type/transaction/TransactionErrors.java | 107 + .../type/transaction/TransactionalState.java | 88 + .../amqp_1_0/type/transaction/TxnCapabilities.java | 144 + .../amqp_1_0/type/transaction/TxnCapability.java | 131 + .../transaction/codec/CoordinatorConstructor.java | 117 + .../type/transaction/codec/CoordinatorWriter.java | 150 + .../type/transaction/codec/DeclareConstructor.java | 99 + .../type/transaction/codec/DeclareWriter.java | 150 + .../transaction/codec/DeclaredConstructor.java | 99 + .../type/transaction/codec/DeclaredWriter.java | 150 + .../transaction/codec/DischargeConstructor.java | 126 + .../type/transaction/codec/DischargeWriter.java | 158 + .../codec/TransactionalStateConstructor.java | 126 + .../codec/TransactionalStateWriter.java | 158 + .../qpid/amqp_1_0/type/transport/AmqpError.java | 227 + .../qpid/amqp_1_0/type/transport/Attach.java | 365 + .../apache/qpid/amqp_1_0/type/transport/Begin.java | 239 + .../apache/qpid/amqp_1_0/type/transport/Close.java | 89 + .../amqp_1_0/type/transport/ConnectionError.java | 107 + .../qpid/amqp_1_0/type/transport/Detach.java | 131 + .../qpid/amqp_1_0/type/transport/Disposition.java | 194 + .../apache/qpid/amqp_1_0/type/transport/End.java | 89 + .../apache/qpid/amqp_1_0/type/transport/Error.java | 111 + .../apache/qpid/amqp_1_0/type/transport/Flow.java | 302 + .../qpid/amqp_1_0/type/transport/LinkError.java | 131 + .../apache/qpid/amqp_1_0/type/transport/Open.java | 281 + .../type/transport/ReceiverSettleMode.java | 95 + .../apache/qpid/amqp_1_0/type/transport/Role.java | 95 + .../amqp_1_0/type/transport/SenderSettleMode.java | 107 + .../qpid/amqp_1_0/type/transport/SessionError.java | 119 + .../qpid/amqp_1_0/type/transport/Transfer.java | 299 + .../type/transport/codec/AttachConstructor.java | 465 + .../type/transport/codec/AttachWriter.java | 254 + .../type/transport/codec/BeginConstructor.java | 303 + .../amqp_1_0/type/transport/codec/BeginWriter.java | 206 + .../type/transport/codec/CloseConstructor.java | 99 + .../amqp_1_0/type/transport/codec/CloseWriter.java | 150 + .../type/transport/codec/DetachConstructor.java | 153 + .../type/transport/codec/DetachWriter.java | 166 + .../transport/codec/DispositionConstructor.java | 234 + .../type/transport/codec/DispositionWriter.java | 190 + .../type/transport/codec/EndConstructor.java | 99 + .../amqp_1_0/type/transport/codec/EndWriter.java | 150 + .../type/transport/codec/ErrorConstructor.java | 169 + .../amqp_1_0/type/transport/codec/ErrorWriter.java | 166 + .../type/transport/codec/FlowConstructor.java | 370 + .../amqp_1_0/type/transport/codec/FlowWriter.java | 230 + .../type/transport/codec/OpenConstructor.java | 371 + .../amqp_1_0/type/transport/codec/OpenWriter.java | 222 + .../type/transport/codec/TransferConstructor.java | 369 + .../type/transport/codec/TransferWriter.java | 230 + java/bdbstore/bin/backup.sh | 2 +- java/bdbstore/bin/storeUpgrade.sh | 41 - java/bdbstore/build.xml | 9 +- java/bdbstore/etc/scripts/bdbtest.sh | 43 - .../src/main/java/BDBStoreUpgrade.log4j.xml | 52 - .../store/berkeleydb/AMQShortStringEncoding.java | 2 +- .../server/store/berkeleydb/AMQShortStringTB.java | 49 - .../store/berkeleydb/AbstractBDBMessageStore.java | 1825 +++ .../server/store/berkeleydb/BDBMessageStore.java | 2234 +-- .../store/berkeleydb/BDBMessageStoreFactory.java | 40 + .../server/store/berkeleydb/BDBStoreUpgrade.java | 1299 -- .../qpid/server/store/berkeleydb/ContentTB.java | 52 - .../server/store/berkeleydb/DatabaseVisitor.java | 49 - .../qpid/server/store/berkeleydb/ExchangeTB.java | 59 - .../server/store/berkeleydb/MessageContentKey.java | 42 - .../server/store/berkeleydb/QueueEntryKey.java | 49 - .../server/store/berkeleydb/StringMapBinding.java | 61 - .../server/store/berkeleydb/UUIDTupleBinding.java | 50 - .../berkeleydb/entry/PreparedTransaction.java | 46 + .../store/berkeleydb/entry/QueueEntryKey.java | 45 + .../qpid/server/store/berkeleydb/entry/Xid.java | 52 + .../store/berkeleydb/keys/MessageContentKey_4.java | 44 - .../store/berkeleydb/keys/MessageContentKey_5.java | 44 - .../store/berkeleydb/records/BindingRecord.java | 62 - .../store/berkeleydb/records/ExchangeRecord.java | 53 - .../store/berkeleydb/records/QueueRecord.java | 66 - .../berkeleydb/tuple/ConfiguredObjectBinding.java | 37 + .../store/berkeleydb/tuple/ContentBinding.java | 52 + .../berkeleydb/tuple/MessageMetaDataBinding.java | 77 + .../tuple/PreparedTransactionBinding.java | 127 + .../store/berkeleydb/tuple/QueueEntryBinding.java | 59 + .../store/berkeleydb/tuple/StringMapBinding.java | 59 + .../store/berkeleydb/tuple/UUIDTupleBinding.java | 48 + .../server/store/berkeleydb/tuple/XidBinding.java | 70 + .../store/berkeleydb/tuples/BindingTuple.java | 25 - .../tuples/BindingTupleBindingFactory.java | 45 - .../store/berkeleydb/tuples/BindingTuple_4.java | 76 - .../berkeleydb/tuples/MessageContentKeyTB_4.java | 47 - .../berkeleydb/tuples/MessageContentKeyTB_5.java | 46 - .../MessageContentKeyTupleBindingFactory.java | 45 - .../berkeleydb/tuples/MessageMetaDataTB_4.java | 170 - .../berkeleydb/tuples/MessageMetaDataTB_5.java | 67 - .../tuples/MessageMetaDataTupleBindingFactory.java | 43 - .../store/berkeleydb/tuples/QueueEntryTB.java | 46 - .../server/store/berkeleydb/tuples/QueueTuple.java | 25 - .../tuples/QueueTupleBindingFactory.java | 46 - .../store/berkeleydb/tuples/QueueTuple_4.java | 70 - .../store/berkeleydb/tuples/QueueTuple_5.java | 73 - .../berkeleydb/tuples/TupleBindingFactory.java | 40 - .../berkeleydb/upgrade/AbstractStoreUpgrade.java | 77 + .../store/berkeleydb/upgrade/CursorOperation.java | 89 + .../store/berkeleydb/upgrade/CursorTemplate.java | 75 + .../store/berkeleydb/upgrade/DatabaseCallable.java | 29 + .../berkeleydb/upgrade/DatabaseEntryCallback.java | 30 + .../store/berkeleydb/upgrade/DatabaseRunnable.java | 30 + .../store/berkeleydb/upgrade/DatabaseTemplate.java | 114 + .../store/berkeleydb/upgrade/StoreUpgrade.java | 31 + .../store/berkeleydb/upgrade/UpgradeFrom4To5.java | 915 ++ .../store/berkeleydb/upgrade/UpgradeFrom5To6.java | 1207 ++ .../upgrade/UpgradeInteractionHandler.java | 37 + .../upgrade/UpgradeInteractionResponse.java | 28 + .../server/store/berkeleydb/upgrade/Upgrader.java | 177 + .../BDBMessageStoreConfigurationTest.java | 14 + .../store/berkeleydb/BDBMessageStoreTest.java | 211 +- .../berkeleydb/BDBStoreUpgradeTestPreparer.java | 63 +- .../server/store/berkeleydb/BDBUpgradeTest.java | 324 +- .../tuple/ConfiguredObjectBindingTest.java | 61 + .../upgrade/AbstractUpgradeTestCase.java | 153 + .../berkeleydb/upgrade/DatabaseTemplateTest.java | 83 + .../berkeleydb/upgrade/UpgradeFrom4to5Test.java | 299 + .../berkeleydb/upgrade/UpgradeFrom5To6Test.java | 395 + .../store/berkeleydb/upgrade/UpgraderTest.java | 138 + .../bdbstore-to-upgrade/test-store/00000000.jdb | Bin 1346092 -> 0 bytes .../upgrade/bdbstore-v4/test-store/00000000.jdb | Bin 0 -> 1357197 bytes .../test/resources/upgrade/bdbstore-v5/readme.txt | 5 + .../upgrade/bdbstore-v5/test-store/00000000.jdb | Bin 0 -> 1357227 bytes .../upgrade/bdbstore-v5/test-store/00000001.jdb | Bin 0 -> 1332881 bytes .../security/access/config/PlainConfiguration.java | 1 - .../security/access/plugins/AccessControlTest.java | 9 +- .../access/plugins/PlainConfigurationTest.java | 6 +- java/broker-plugins/experimental/info/MANIFEST.MF | 16 - .../experimental/info/build.properties | 31 - java/broker-plugins/experimental/info/build.xml | 39 - .../main/java/org/apache/qpid/info/Activator.java | 212 - .../main/java/org/apache/qpid/info/AppInfo.java | 96 - .../src/main/java/org/apache/qpid/info/Info.java | 143 - .../java/org/apache/qpid/info/InfoService.java | 30 - .../java/org/apache/qpid/info/InfoServiceImpl.java | 66 - .../main/java/org/apache/qpid/info/SystemInfo.java | 95 - .../java/org/apache/qpid/info/util/HttpPoster.java | 130 - .../org/apache/qpid/info/util/IniFileReader.java | 193 - .../java/org/apache/qpid/info/util/SoapClient.java | 155 - .../java/org/apache/qpid/info/util/XMLWriter.java | 102 - .../apache/qpid/info/systest/InfoPluginTest.java | 277 - .../org/apache/qpid/info/test/HttpPosterTest.java | 107 - .../apache/qpid/info/test/InfoServiceImplTest.java | 63 - .../org/apache/qpid/info/test/InfoServlet.java | 57 - .../java/org/apache/qpid/info/test/InfoTest.java | 114 - .../apache/qpid/info/test/IniFileReaderTest.java | 137 - .../org/apache/qpid/info/test/SoapClientTest.java | 209 - .../org/apache/qpid/info/test/SystemInfoTest.java | 57 - .../org/apache/qpid/info/test/XMLWriterTest.java | 133 - .../shutdown/src/main/java/shutdown.bnd | 2 +- .../exchanges/diagnostic/DiagnosticExchange.java | 10 +- .../diagnostic/DiagnosticExchangeType.java | 6 +- .../extras/exchanges/example/TestExchange.java | 7 +- .../extras/exchanges/example/TestExchangeType.java | 6 +- java/broker/bin/create-example-ssl-stores.bat | 36 - java/broker/bin/create-example-ssl-stores.sh | 38 - java/broker/build.xml | 2 +- java/broker/etc/config.xml | 3 +- java/broker/etc/virtualhosts.xml | 12 +- java/broker/src/main/java/broker.bnd | 2 +- .../org/apache/qpid/qmf/ManagementExchange.java | 22 +- .../main/java/org/apache/qpid/qmf/QMFService.java | 5 + .../apache/qpid/server/AMQBrokerManagerMBean.java | 74 +- .../java/org/apache/qpid/server/AMQChannel.java | 92 +- .../main/java/org/apache/qpid/server/Broker.java | 147 +- .../java/org/apache/qpid/server/BrokerOptions.java | 3 - .../src/main/java/org/apache/qpid/server/Main.java | 7 + .../org/apache/qpid/server/ProtocolExclusion.java | 3 +- .../org/apache/qpid/server/binding/Binding.java | 2 +- .../apache/qpid/server/binding/BindingFactory.java | 94 +- .../server/configuration/ServerConfiguration.java | 13 +- .../ServerNetworkTransportConfiguration.java | 18 +- .../server/configuration/VirtualHostConfig.java | 2 - .../configuration/VirtualHostConfiguration.java | 30 +- .../qpid/server/connection/ConnectionRegistry.java | 12 +- .../server/connection/IConnectionRegistry.java | 9 +- .../qpid/server/exchange/AbstractExchange.java | 27 +- .../server/exchange/DefaultExchangeFactory.java | 27 +- .../server/exchange/DefaultExchangeRegistry.java | 53 +- .../qpid/server/exchange/DirectExchange.java | 11 +- .../org/apache/qpid/server/exchange/Exchange.java | 6 +- .../qpid/server/exchange/ExchangeFactory.java | 7 + .../qpid/server/exchange/ExchangeInitialiser.java | 5 +- .../qpid/server/exchange/ExchangeRegistry.java | 7 +- .../apache/qpid/server/exchange/ExchangeType.java | 4 +- .../qpid/server/exchange/FanoutExchange.java | 10 +- .../qpid/server/exchange/HeadersBinding.java | 42 +- .../qpid/server/exchange/HeadersExchange.java | 42 +- .../apache/qpid/server/exchange/TopicExchange.java | 216 +- .../org/apache/qpid/server/federation/Bridge.java | 10 +- .../apache/qpid/server/federation/BrokerLink.java | 4 +- .../qpid/server/filter/SimpleFilterManager.java | 6 + .../handler/ConnectionOpenMethodHandler.java | 9 +- .../server/handler/ExchangeDeclareHandler.java | 29 +- .../qpid/server/handler/QueueBindHandler.java | 2 +- .../qpid/server/handler/QueueDeclareHandler.java | 12 +- .../qpid/server/handler/QueueDeleteHandler.java | 2 +- .../qpid/server/logging/actors/CurrentActor.java | 16 +- .../messages/ConfigStore_logmessages.properties | 3 +- .../messages/MessageStore_logmessages.properties | 6 +- .../messages/TransactionLog_logmessages.properties | 9 +- .../server/logging/subjects/BindingLogSubject.java | 3 +- .../logging/subjects/MessageStoreLogSubject.java | 8 +- .../AbstractAMQManagedConnectionObject.java | 20 + .../management/JMXManagedObjectRegistry.java | 4 +- .../qpid/server/message/MessageMetaData_0_10.java | 11 + .../qpid/server/message/MessageMetaData_1_0.java | 522 + .../java/org/apache/qpid/server/model/Binding.java | 75 + .../server/model/ConfigurationChangeListener.java | 38 + .../apache/qpid/server/model/ConfiguredObject.java | 229 + .../org/apache/qpid/server/model/Consumer.java | 73 + .../org/apache/qpid/server/model/Exchange.java | 91 + .../model/IllegalStateTransitionException.java | 43 + .../apache/qpid/server/model/LifetimePolicy.java | 27 + .../org/apache/qpid/server/model/Publisher.java | 25 + .../java/org/apache/qpid/server/model/Queue.java | 146 + .../java/org/apache/qpid/server/model/State.java | 30 + .../org/apache/qpid/server/model/Statistics.java | 25 + .../apache/qpid/server/model/UUIDGenerator.java | 54 + .../qpid/server/protocol/AMQProtocolEngine.java | 8 +- .../qpid/server/protocol/AMQSessionModel.java | 8 +- .../qpid/server/protocol/AmqpProtocolVersion.java | 2 +- .../protocol/MultiVersionProtocolEngine.java | 64 +- .../qpid/server/protocol/ProtocolEngine_1_0_0.java | 394 + .../server/protocol/ProtocolEngine_1_0_0_SASL.java | 449 + .../qpid/server/protocol/v1_0/Connection_1_0.java | 98 + .../qpid/server/protocol/v1_0/Destination.java | 28 + .../server/protocol/v1_0/ExchangeDestination.java | 108 + .../qpid/server/protocol/v1_0/LinkRegistry.java | 59 + .../apache/qpid/server/protocol/v1_0/Link_1_0.java | 26 + .../qpid/server/protocol/v1_0/Message_1_0.java | 172 + .../server/protocol/v1_0/QueueDestination.java | 100 + .../server/protocol/v1_0/ReceivingDestination.java | 35 + .../protocol/v1_0/ReceivingLinkAttachment.java | 51 + .../server/protocol/v1_0/ReceivingLink_1_0.java | 305 + .../server/protocol/v1_0/SendingDestination.java | 27 + .../protocol/v1_0/SendingLinkAttachment.java | 44 + .../qpid/server/protocol/v1_0/SendingLink_1_0.java | 648 + .../qpid/server/protocol/v1_0/Session_1_0.java | 446 + .../server/protocol/v1_0/Subscription_1_0.java | 634 + .../protocol/v1_0/TxnCoordinatorLink_1_0.java | 195 + .../qpid/server/protocol/v1_0/UnsettledAction.java | 8 + .../apache/qpid/server/queue/AMQPriorityQueue.java | 9 +- .../org/apache/qpid/server/queue/AMQQueue.java | 6 +- .../apache/qpid/server/queue/AMQQueueFactory.java | 58 +- .../apache/qpid/server/queue/AMQQueueMBean.java | 12 +- .../apache/qpid/server/queue/ConflationQueue.java | 13 +- .../qpid/server/queue/DefaultQueueRegistry.java | 38 + .../apache/qpid/server/queue/IncomingMessage.java | 41 +- .../apache/qpid/server/queue/OutOfOrderQueue.java | 29 +- .../qpid/server/queue/PriorityQueueList.java | 50 +- .../org/apache/qpid/server/queue/QueueContext.java | 9 + .../apache/qpid/server/queue/QueueEntryImpl.java | 17 +- .../qpid/server/queue/QueueEntryVisitor.java | 22 + .../apache/qpid/server/queue/QueueRegistry.java | 5 + .../apache/qpid/server/queue/SimpleAMQQueue.java | 223 +- .../qpid/server/queue/SimpleQueueEntryList.java | 25 +- .../org/apache/qpid/server/queue/SortedQueue.java | 11 +- .../qpid/server/registry/ApplicationRegistry.java | 60 +- .../qpid/server/registry/BrokerConfigAdapter.java | 1 - .../ConfigurationFileApplicationRegistry.java | 18 - .../auth/manager/AuthenticationManager.java | 3 + .../PrincipalDatabaseAuthenticationManager.java | 5 + .../sasl/anonymous/AnonymousSaslServerFactory.java | 2 +- .../security/auth/sasl/plain/PlainSaslServer.java | 63 +- .../qpid/server/store/AbstractMessageStore.java | 43 - .../server/store/ConfigurationRecoveryHandler.java | 15 +- .../qpid/server/store/ConfiguredObjectHelper.java | 183 + .../qpid/server/store/ConfiguredObjectRecord.java | 65 + .../qpid/server/store/DerbyMessageStore.java | 2363 --- .../server/store/DurableConfigurationStore.java | 29 +- .../java/org/apache/qpid/server/store/Event.java | 32 + .../apache/qpid/server/store/EventListener.java | 25 + .../org/apache/qpid/server/store/EventManager.java | 55 + .../qpid/server/store/MemoryMessageStore.java | 185 +- .../server/store/MemoryMessageStoreFactory.java | 37 + .../qpid/server/store/MessageMetaDataType.java | 5 +- .../org/apache/qpid/server/store/MessageStore.java | 110 +- .../qpid/server/store/MessageStoreConstants.java | 27 + .../qpid/server/store/MessageStoreFactory.java | 27 + .../apache/qpid/server/store/NullMessageStore.java | 146 + .../server/store/OperationalLoggingListener.java | 73 + .../java/org/apache/qpid/server/store/State.java | 38 + .../org/apache/qpid/server/store/StateManager.java | 151 + .../org/apache/qpid/server/store/StoreFuture.java | 40 + .../qpid/server/store/StoredMemoryMessage.java | 4 +- .../apache/qpid/server/store/StoredMessage.java | 2 +- .../org/apache/qpid/server/store/Transaction.java | 81 + .../store/TransactionLogRecoveryHandler.java | 13 +- .../qpid/server/store/TransactionLogResource.java | 4 +- .../qpid/server/store/derby/DerbyMessageStore.java | 2449 +++ .../store/derby/DerbyMessageStoreFactory.java | 40 + .../qpid/server/subscription/Subscription.java | 8 +- .../qpid/server/subscription/SubscriptionImpl.java | 14 +- .../server/subscription/Subscription_0_10.java | 35 +- .../server/transport/ServerConnectionDelegate.java | 24 +- .../qpid/server/transport/ServerSession.java | 194 +- .../server/transport/ServerSessionDelegate.java | 446 +- .../qpid/server/txn/AlreadyKnownDtxException.java | 32 + .../server/txn/AsyncAutoCommitTransaction.java | 35 +- .../qpid/server/txn/AutoCommitTransaction.java | 11 +- .../qpid/server/txn/DistributedTransaction.java | 247 + .../java/org/apache/qpid/server/txn/DtxBranch.java | 349 + .../org/apache/qpid/server/txn/DtxException.java | 44 + .../qpid/server/txn/DtxNotSelectedException.java | 30 + .../org/apache/qpid/server/txn/DtxRegistry.java | 333 + .../server/txn/IncorrectDtxStateException.java | 32 + .../qpid/server/txn/JoinAndResumeDtxException.java | 32 + .../apache/qpid/server/txn/LocalTransaction.java | 3 +- .../qpid/server/txn/NotAssociatedDtxException.java | 32 + .../qpid/server/txn/RollbackOnlyDtxException.java | 32 + .../apache/qpid/server/txn/ServerTransaction.java | 5 +- .../server/txn/SuspendAndFailDtxException.java | 32 + .../qpid/server/txn/TimeoutDtxException.java | 32 + .../qpid/server/txn/UnknownDtxBranchException.java | 32 + .../apache/qpid/server/util/MapJsonSerializer.java | 69 + .../org/apache/qpid/server/virtualhost/State.java | 29 + .../qpid/server/virtualhost/VirtualHost.java | 21 +- .../VirtualHostConfigRecoveryHandler.java | 259 +- .../qpid/server/virtualhost/VirtualHostImpl.java | 650 +- .../qpid/server/AMQBrokerManagerMBeanTest.java | 3 +- .../org/apache/qpid/server/AMQChannelTest.java | 52 + .../server/configuration/MockConnectionConfig.java | 20 + .../VirtualHostConfigurationTest.java | 3 +- .../exchange/AbstractHeadersExchangeTestBase.java | 57 +- .../qpid/server/exchange/ExchangeMBeanTest.java | 13 +- .../qpid/server/exchange/TopicExchangeTest.java | 2 +- .../logging/messages/MessageStoreMessagesTest.java | 58 +- .../subjects/MessageStoreLogSubjectTest.java | 4 +- .../server/plugins/OsgiSystemPackageUtilTest.java | 4 +- .../protocol/AMQProtocolSessionMBeanTest.java | 4 +- .../protocol/InternalTestProtocolSession.java | 5 +- .../MultiVersionProtocolEngineFactoryTest.java | 18 +- .../qpid/server/queue/AMQQueueAlertTest.java | 39 +- .../qpid/server/queue/AMQQueueFactoryTest.java | 5 +- .../qpid/server/queue/AMQQueueMBeanTest.java | 19 +- .../java/org/apache/qpid/server/queue/AckTest.java | 13 +- .../org/apache/qpid/server/queue/MockAMQQueue.java | 5 +- .../qpid/server/queue/MockStoredMessage.java | 6 +- .../qpid/server/queue/PriorityQueueListTest.java | 117 + .../qpid/server/queue/QueueEntryListTestBase.java | 33 + .../qpid/server/queue/SimpleAMQQueueTest.java | 59 +- .../server/queue/SimpleQueueEntryImplTest.java | 20 + .../server/queue/SimpleQueueEntryListTest.java | 19 +- .../server/queue/SortedQueueEntryListTest.java | 16 +- .../registry/ApplicationRegistryShutdownTest.java | 5 +- .../auth/rmi/RMIPasswordAuthenticatorTest.java | 30 +- .../security/auth/sasl/SaslServerTestCase.java | 2 +- .../store/DurableConfigurationStoreTest.java | 377 + .../apache/qpid/server/store/EventManagerTest.java | 72 + .../apache/qpid/server/store/MessageStoreTest.java | 16 +- .../store/OperationalLoggingListenerTest.java | 181 + .../qpid/server/store/ReferenceCountingTest.java | 4 +- .../qpid/server/store/SkeletonMessageStore.java | 157 - .../apache/qpid/server/store/StateManagerTest.java | 195 + .../qpid/server/store/TestMemoryMessageStore.java | 98 - .../server/store/TestableMemoryMessageStore.java | 57 +- .../store/TestableMemoryMessageStoreFactory.java | 37 + .../qpid/server/subscription/MockSubscription.java | 4 + .../qpid/server/transport/ServerSessionTest.java | 67 + .../qpid/server/txn/MockStoreTransaction.java | 54 +- .../qpid/server/util/InternalBrokerBaseCase.java | 7 +- .../qpid/server/util/MapJsonSerializerTest.java | 53 + .../qpid/server/virtualhost/MockVirtualHost.java | 26 +- .../server/virtualhost/VirtualHostImplTest.java | 84 +- java/build.deps | 43 +- java/build.xml | 20 +- java/client/src/main/java/client.bnd | 2 +- .../org/apache/qpid/client/AMQBrokerDetails.java | 8 +- .../java/org/apache/qpid/client/AMQConnection.java | 29 +- .../qpid/client/AMQConnectionDelegate_0_10.java | 2 + .../org/apache/qpid/client/AMQQueueBrowser.java | 68 +- .../java/org/apache/qpid/client/AMQSession.java | 141 +- .../org/apache/qpid/client/AMQSession_0_10.java | 64 +- .../org/apache/qpid/client/AMQSession_0_8.java | 19 +- .../apache/qpid/client/BasicMessageConsumer.java | 18 +- .../apache/qpid/client/BasicMessageProducer.java | 222 +- .../qpid/client/BasicMessageProducer_0_10.java | 4 +- .../qpid/client/BasicMessageProducer_0_8.java | 8 +- .../java/org/apache/qpid/client/Closeable.java | 7 +- .../org/apache/qpid/client/XAResourceImpl.java | 25 +- .../java/org/apache/qpid/client/XASessionImpl.java | 16 +- .../client/handler/ClientMethodDispatcherImpl.java | 4 +- .../qpid/client/message/FieldTableSupport.java | 7 +- .../qpid/client/protocol/AMQProtocolHandler.java | 3 +- .../qpid/client/protocol/AMQProtocolSession.java | 15 +- .../apache/qpid/client/util/BlockingWaiter.java | 39 +- .../jndi/PropertiesFileInitialContextFactory.java | 62 +- .../java/org/apache/qpid/jndi/JNDITest.properties | 28 + .../PropertiesFileInitialContextFactoryTest.java | 95 + .../java/org/apache/qpid/jndi/hello.properties | 27 + .../qpid/test/unit/jndi/JNDIPropertyFileTest.java | 88 - .../apache/qpid/test/unit/jndi/JNDITest.properties | 28 - .../qpid/test/unit/message/TestAMQSession.java | 2 +- java/common.xml | 2 +- java/common/src/main/java/common.bnd | 2 +- .../org/apache/qpid/codec/MarkableDataInput.java | 20 + .../org/apache/qpid/common/AMQPFilterTypes.java | 4 +- .../org/apache/qpid/framing/AMQShortString.java | 5 + .../apache/qpid/framing/ByteArrayDataInput.java | 20 + .../org/apache/qpid/framing/ContentHeaderBody.java | 11 - .../org/apache/qpid/framing/EncodingUtils.java | 3 - .../org/apache/qpid/framing/ExtendedDataInput.java | 20 + .../qpid/properties/ConnectionStartProperties.java | 21 +- .../java/org/apache/qpid/transport/Connection.java | 1 + .../transport/NetworkTransportConfiguration.java | 4 + .../main/java/org/apache/qpid/transport/Range.java | 5 + .../java/org/apache/qpid/transport/RangeSet.java | 2 + .../org/apache/qpid/transport/RangeSetImpl.java | 62 + .../org/apache/qpid/transport/ServerDelegate.java | 8 +- .../java/org/apache/qpid/transport/Session.java | 16 +- .../qpid/transport/codec/AbstractEncoder.java | 2 + .../apache/qpid/transport/network/Assembler.java | 2 +- .../transport/network/io/IoNetworkTransport.java | 2 +- .../org/apache/qpid/test/utils/QpidTestCase.java | 18 +- .../org/apache/qpid/transport/RangeSetTest.java | 114 + java/genpom | 34 +- java/integrationtests/README.txt | 13 - java/integrationtests/bin/interoptests.py | 180 - java/integrationtests/build.xml | 28 - .../docs/RunningSustainedTests.txt | 17 - java/integrationtests/jar-with-dependencies.xml | 47 - .../interop/clienttestcases/TestCase1DummyRun.java | 135 - .../interop/clienttestcases/TestCase2BasicP2P.java | 209 - .../clienttestcases/TestCase3BasicPubSub.java | 239 - .../clienttestcases/TestCase4P2PMessageSize.java | 214 - .../TestCase5PubSubMessageSize.java | 243 - .../testcases/InteropTestCase1DummyRun.java | 84 - .../testcases/InteropTestCase2BasicP2P.java | 90 - .../testcases/InteropTestCase3BasicPubSub.java | 88 - .../testcases/InteropTestCase4P2PMessageSize.java | 193 - .../InteropTestCase5PubSubMessageSize.java | 193 - .../qpid/sustained/SustainedClientTestCase.java | 906 -- .../apache/qpid/sustained/SustainedTestCase.java | 126 - .../src/resources/sustained-log4j.xml | 69 - java/ivy.xml | 2 +- java/jca/.gitignore | 1 - java/jca/README.txt | 127 +- java/jca/example/.gitignore | 19 + java/jca/example/README-EXAMPLE.txt | 235 + java/jca/example/README-GERONIMO.txt | 69 + java/jca/example/README-GLASSFISH.txt | 84 + java/jca/example/README-JBOSS.txt | 107 + java/jca/example/README-JBOSS7.txt | 116 + java/jca/example/README.txt | 277 - java/jca/example/build-geronimo-properties.xml | 21 +- java/jca/example/build-glassfish-properties.xml | 135 + java/jca/example/build-jboss-properties.xml | 7 +- java/jca/example/build-jboss7-properties.xml | 133 + java/jca/example/build.xml | 25 +- java/jca/example/conf/geronimo-application.xml | 2 +- java/jca/example/conf/geronimo-ra.xml | 40 +- java/jca/example/conf/glassfish-ejb-jar.xml | 70 + java/jca/example/conf/glassfish-resources.xml | 74 + java/jca/example/conf/glassfish-web.xml | 26 + java/jca/example/conf/jboss-ejb-client.properties | 12 + java/jca/example/conf/jboss-web.xml | 5 + java/jca/example/conf/log4j.properties | 18 + java/jca/example/conf/qpid-jca-ds.xml | 27 +- java/jca/example/conf/qpid-standalone.xml | 422 + java/jca/example/conf/web.xml | 11 + java/jca/example/qpid-jca-example-properties.xml | 15 +- .../example/client/QpidRequestResponseClient.java | 2 +- .../jca/example/ejb/QpidGoodByeListenerBean.java | 2 +- .../jca/example/ejb/QpidGoodByeSubscriberBean.java | 3 +- .../jca/example/ejb/QpidHelloListenerBean.java | 4 +- .../jca/example/ejb/QpidHelloSubscriberBean.java | 5 +- .../qpid/jca/example/ejb/QpidJMSResponderBean.java | 13 +- .../apache/qpid/jca/example/ejb/QpidTestBean.java | 4 +- .../example/web/QpidRequestResponseServlet.java | 283 + .../qpid/jca/example/web/QpidTestServlet.java | 47 +- .../qpid/ra/ConnectionFactoryProperties.java | 6 +- .../qpid/ra/QpidRAConnectionRequestInfo.java | 36 +- .../apache/qpid/ra/QpidRAManagedConnection.java | 109 +- .../qpid/ra/QpidRAManagedConnectionFactory.java | 4 +- .../java/org/apache/qpid/ra/QpidRAProperties.java | 48 +- .../java/org/apache/qpid/ra/QpidRASession.java | 2 + .../org/apache/qpid/ra/QpidRASessionFactory.java | 2 +- .../apache/qpid/ra/QpidRASessionFactoryImpl.java | 12 +- .../java/org/apache/qpid/ra/QpidRASessionImpl.java | 2 +- .../org/apache/qpid/ra/QpidResourceAdapter.java | 140 +- .../qpid/ra/admin/QpidConnectionFactoryProxy.java | 27 +- .../org/apache/qpid/ra/admin/QpidQueueImpl.java | 25 - .../org/apache/qpid/ra/inflow/QpidActivation.java | 501 +- .../apache/qpid/ra/inflow/QpidActivationSpec.java | 29 +- .../qpid/ra/inflow/QpidExceptionHandler.java | 339 + .../apache/qpid/ra/inflow/QpidMessageHandler.java | 139 +- .../ra/tm/GlassfishTransactionManagerLocator.java | 63 + .../ra/tm/JBoss7TransactionManagerLocator.java | 20 + .../qpid/ra/tm/WLSTransactionManagerLocator.java | 64 + java/jca/src/main/resources/META-INF/ra.xml | 42 +- .../org/apache/qpid/ra/QpidActivationSpecTest.java | 45 + .../apache/qpid/ra/QpidResourceAdapterTest.java | 78 + java/junit-toolkit/build.xml | 26 - .../junit/concurrency/DefaultThreadFactory.java | 48 - .../concurrency/PossibleDeadlockException.java | 46 - .../qpid/junit/concurrency/TestRunnable.java | 239 - .../junit/concurrency/ThreadTestCoordinator.java | 486 - .../qpid/junit/concurrency/ThreadTestExample.java | 145 - .../org/apache/qpid/junit/concurrency/package.html | 28 - .../qpid/junit/extensions/AsymptoticTestCase.java | 303 - .../junit/extensions/AsymptoticTestDecorator.java | 173 - .../apache/qpid/junit/extensions/BaseThrottle.java | 98 - .../qpid/junit/extensions/BatchedThrottle.java | 94 - .../junit/extensions/DurationTestDecorator.java | 205 - .../qpid/junit/extensions/InstrumentedTest.java | 66 - .../qpid/junit/extensions/NullResultPrinter.java | 92 - .../ParameterVariationTestDecorator.java | 175 - .../qpid/junit/extensions/ScaledTestDecorator.java | 391 - .../qpid/junit/extensions/SetupTaskAware.java | 55 - .../qpid/junit/extensions/SetupTaskHandler.java | 92 - .../qpid/junit/extensions/ShutdownHookable.java | 42 - .../qpid/junit/extensions/SleepThrottle.java | 81 - .../apache/qpid/junit/extensions/TKTestResult.java | 654 - .../apache/qpid/junit/extensions/TKTestRunner.java | 694 - .../TestRunnerImprovedErrorHandling.java | 131 - .../qpid/junit/extensions/TestThreadAware.java | 54 - .../org/apache/qpid/junit/extensions/Throttle.java | 73 - .../qpid/junit/extensions/TimingController.java | 198 - .../junit/extensions/TimingControllerAware.java | 43 - .../extensions/WrappedSuiteTestDecorator.java | 134 - .../extensions/listeners/CSVTestListener.java | 572 - .../extensions/listeners/ConsoleTestListener.java | 274 - .../junit/extensions/listeners/TKTestListener.java | 142 - .../extensions/listeners/XMLTestListener.java | 410 - .../qpid/junit/extensions/listeners/package.html | 27 - .../org/apache/qpid/junit/extensions/package.html | 33 - .../junit/extensions/util/CommandLineParser.java | 787 - .../extensions/util/ContextualProperties.java | 494 - .../qpid/junit/extensions/util/MathUtils.java | 428 - .../junit/extensions/util/ParsedProperties.java | 390 - .../apache/qpid/junit/extensions/util/SizeOf.java | 94 - .../qpid/junit/extensions/util/StackQueue.java | 131 - .../extensions/util/TestContextProperties.java | 202 - .../qpid/junit/extensions/util/TestUtils.java | 54 - .../apache/qpid/junit/extensions/util/package.html | 27 - java/lib/gson-2.0.jar | Bin 0 -> 202952 bytes java/lib/jackson-core-asl-1.9.0.jar | Bin 0 -> 228286 bytes java/lib/jackson-mapper-asl-1.9.0.jar | Bin 0 -> 764075 bytes java/lib/jetty-6.1.14.jar | Bin 516429 -> 0 bytes java/lib/jetty-servlet-tester-6.1.14.jar | Bin 9206 -> 0 bytes java/lib/jetty-util-6.1.14.jar | Bin 163122 -> 0 bytes java/lib/mockito-all-1.9.0.jar | Bin 0 -> 1495219 bytes java/lib/org.apache.felix.framework-2.0.5.jar | Bin 391763 -> 0 bytes java/lib/org.apache.felix.main-2.0.5.jar | Bin 0 -> 391763 bytes java/lib/poms/commons-digester-1.8.1.xml | 6 + java/lib/poms/jackson-core-asl-1.9.0.xml | 22 + java/lib/poms/jackson-mapper-asl-1.9.0.xml | 22 + java/lib/poms/org.apache.felix.framework-2.0.5.xml | 22 - java/lib/poms/org.apache.felix.main-2.0.5.xml | 40 + java/lib/poms/org.osgi.core-1.0.0.xml | 22 - java/lib/poms/xalan-2.7.0.xml | 8 + java/lib/servlet-api.jar | Bin 88224 -> 0 bytes .../common/src/main/java/management-common.bnd | 2 +- .../management/eclipse-plugin/META-INF/MANIFEST.MF | 2 +- .../qpid/management/ui/ManagementConsoleTest.java | 4 +- java/module.xml | 6 +- java/perftests/RunningPerformanceTests.txt | 141 - java/perftests/bin/monitoring/monitor-broker.sh | 221 - java/perftests/bin/monitoring/runTests.sh | 148 - .../bin/monitoring/stop-monitored-broker.sh | 124 - java/perftests/bin/processing/process.sh | 388 - java/perftests/bin/processing/processAll.sh | 58 - java/perftests/bin/processing/processTests.py | 850 - java/perftests/bin/run_many.sh | 30 - java/perftests/bin/topicListener.sh | 32 - java/perftests/bin/topicPublisher.sh | 31 - java/perftests/build.xml | 318 +- java/perftests/dist-zip.xml | 45 - .../chartdefs/AcknowledgementModesAutoAck.chartdef | 28 + .../AcknowledgementModesTransacted.chartdef | 28 + java/perftests/etc/chartdefs/BatchSize.chartdef | 28 + .../chartdefs/MessageSizeNonPersistent.chartdef | 27 + .../etc/chartdefs/MessageSizePersistent.chartdef | 29 + java/perftests/etc/chartdefs/QueueTypes.chartdef | 28 + .../chartdefs/VaryingNumberOfConsumers.chartdef | 35 + .../chartdefs/VaryingNumberOfProducers.chartdef | 35 + java/perftests/etc/jndi/activemq.properties | 20 - java/perftests/etc/jndi/failovertest.properties | 19 - java/perftests/etc/jndi/perftests.properties | 19 - java/perftests/etc/jndi/swiftmq.properties | 20 - java/perftests/etc/log4j.properties | 28 + java/perftests/etc/perftests-jndi.properties | 26 + java/perftests/etc/perftests.log4j | 46 - java/perftests/etc/scripts/CTQ-Qpid-1.sh | 21 - java/perftests/etc/scripts/CTQ-Qpid-2.sh | 21 - java/perftests/etc/scripts/CTQ-Qpid-3.sh | 21 - java/perftests/etc/scripts/CTQ-Qpid-4.sh | 21 - java/perftests/etc/scripts/CTQ-Qpid-5.sh | 21 - java/perftests/etc/scripts/CTQ-Qpid-6.sh | 21 - java/perftests/etc/scripts/Connections.sh | 20 - java/perftests/etc/scripts/JobQueue.sh | 20 - java/perftests/etc/scripts/Latency.sh | 21 - java/perftests/etc/scripts/MessageSize.sh | 20 - java/perftests/etc/scripts/PT-Qpid-13.sh | 42 - java/perftests/etc/scripts/PT-Qpid-14.sh | 41 - java/perftests/etc/scripts/Reliability.sh | 20 - java/perftests/etc/scripts/RunAll.sh | 23 - java/perftests/etc/scripts/RunCore.sh | 22 - java/perftests/etc/scripts/Test-ActiveMQ.sh | 32 - java/perftests/etc/scripts/Test-SwiftMQ.sh | 30 - java/perftests/etc/scripts/Throughput.sh | 20 - java/perftests/etc/scripts/drainBroker.sh | 41 - java/perftests/etc/scripts/extractResults.sh | 34 - .../etc/scripts/extractThroughputResults.sh | 51 - java/perftests/etc/scripts/fillBroker.sh | 41 - java/perftests/etc/scripts/sendAndWaitClient.sh | 22 - java/perftests/etc/scripts/testWithPreFill.sh | 41 - .../etc/testdefs/short/AcknowledgementModes.json | 138 + java/perftests/etc/testdefs/short/BatchSize.json | 84 + java/perftests/etc/testdefs/short/MessageSize.json | 213 + java/perftests/etc/testdefs/short/QueueTypes.json | 16198 ++++++++++++++++++ .../short/VaryingNumberOfParticipants.json | 2981 ++++ .../testdefs/standard/AcknowledgementModes.json | 138 + .../perftests/etc/testdefs/standard/BatchSize.json | 84 + .../etc/testdefs/standard/MessageSize.json | 213 + .../etc/testdefs/standard/QueueTypes.json | 16205 +++++++++++++++++++ .../etc/testdefs/standard/QueuesWithSelectors.json | 2036 +++ .../standard/VaryingNumberOfParticipants.json | 2981 ++++ java/perftests/example/PQBT-AA-Qpid-01.json | 795 + java/perftests/example/TQBT-TX-Qpid-01.json | 843 + java/perftests/example/brokerconfig/log4j.xml | 125 + java/perftests/example/brokerconfig/passwd | 23 + .../example/brokerconfig/virtualhosts.xml | 67 + java/perftests/example/config-one-test.json | 55 + .../config-stress-testing-manyp-c1-with-psfc.json | 162 + java/perftests/example/config-stress-testing.json | 84 + java/perftests/example/config-two-tests.json | 117 + java/perftests/example/log4j-client.properties | 29 + java/perftests/example/log4j.properties | 35 + java/perftests/example/perftests-jndi.properties | 26 + java/perftests/example/run-client.sh | 21 + java/perftests/example/run.sh | 22 + java/perftests/generate-scripts | 74 - java/perftests/jar-with-dependencies.xml | 91 - java/perftests/scripts.xml | 328 - .../qpid/client/message/TestMessageFactory.java | 117 - .../config/AMQConnectionFactoryInitialiser.java | 47 - .../org/apache/qpid/config/AbstractConfig.java | 69 - .../qpid/config/ConnectionFactoryInitialiser.java | 29 - .../java/org/apache/qpid/config/Connector.java | 43 - .../org/apache/qpid/config/ConnectorConfig.java | 28 - .../config/JBossConnectionFactoryInitialiser.java | 112 - .../org/apache/qpid/disttest/AbstractRunner.java | 74 + .../org/apache/qpid/disttest/ArgumentParser.java | 44 + .../org/apache/qpid/disttest/ClientRunner.java | 94 + .../org/apache/qpid/disttest/ControllerRunner.java | 238 + .../qpid/disttest/DistributedTestConstants.java | 33 + .../qpid/disttest/DistributedTestException.java | 66 + .../java/org/apache/qpid/disttest/Visitor.java | 76 + .../org/apache/qpid/disttest/client/Client.java | 208 + .../qpid/disttest/client/ClientCommandVisitor.java | 98 + .../apache/qpid/disttest/client/ClientState.java | 25 + .../qpid/disttest/client/ConsumerParticipant.java | 251 + .../qpid/disttest/client/MessageProvider.java | 212 + .../apache/qpid/disttest/client/Participant.java | 31 + .../qpid/disttest/client/ParticipantExecutor.java | 136 + .../client/ParticipantExecutorRegistry.java | 45 + .../disttest/client/ParticipantResultFactory.java | 100 + .../qpid/disttest/client/ProducerParticipant.java | 174 + .../client/property/GeneratedPropertySupport.java | 68 + .../client/property/GeneratedPropertyValue.java | 27 + .../client/property/ListPropertyValue.java | 122 + .../property/NumericGeneratedPropertySupport.java | 179 + .../disttest/client/property/PropertyValue.java | 27 + .../client/property/PropertyValueFactory.java | 46 + .../client/property/RandomPropertyValue.java | 47 + .../client/property/RangePropertyValue.java | 129 + .../client/property/SimplePropertyValue.java | 79 + .../qpid/disttest/controller/ClientRegistry.java | 96 + .../qpid/disttest/controller/CommandForClient.java | 46 + .../qpid/disttest/controller/CommandListener.java | 31 + .../qpid/disttest/controller/Controller.java | 228 + .../disttest/controller/ParticipatingClients.java | 94 + .../disttest/controller/ResultsForAllTests.java | 49 + .../qpid/disttest/controller/TestResult.java | 70 + .../qpid/disttest/controller/TestRunner.java | 342 + .../disttest/controller/TestRunnerFactory.java | 31 + .../disttest/controller/config/ClientConfig.java | 113 + .../qpid/disttest/controller/config/Config.java | 81 + .../disttest/controller/config/ConfigReader.java | 52 + .../controller/config/ConnectionConfig.java | 91 + .../disttest/controller/config/ConsumerConfig.java | 65 + .../disttest/controller/config/IterationValue.java | 86 + .../controller/config/MessageProviderConfig.java | 60 + .../controller/config/ParticipantConfig.java | 64 + .../disttest/controller/config/ProducerConfig.java | 90 + .../disttest/controller/config/QueueConfig.java | 69 + .../disttest/controller/config/SessionConfig.java | 114 + .../disttest/controller/config/TestConfig.java | 117 + .../disttest/controller/config/TestInstance.java | 102 + .../qpid/disttest/jms/ClientJmsDelegate.java | 592 + .../qpid/disttest/jms/ControllerJmsDelegate.java | 210 + .../qpid/disttest/jms/JmsMessageAdaptor.java | 124 + .../apache/qpid/disttest/jms/QpidQueueCreator.java | 97 + .../org/apache/qpid/disttest/jms/QueueCreator.java | 31 + .../org/apache/qpid/disttest/json/JsonHandler.java | 43 + .../qpid/disttest/json/PropertyValueAdapter.java | 147 + .../org/apache/qpid/disttest/message/Command.java | 56 + .../apache/qpid/disttest/message/CommandType.java | 39 + .../message/ConsumerParticipantResult.java | 118 + .../disttest/message/CreateConnectionCommand.java | 58 + .../disttest/message/CreateConsumerCommand.java | 108 + .../message/CreateMessageProviderCommand.java | 54 + .../disttest/message/CreateParticpantCommand.java | 103 + .../disttest/message/CreateProducerCommand.java | 106 + .../disttest/message/CreateResponderCommand.java | 28 + .../disttest/message/CreateSessionCommand.java | 62 + .../apache/qpid/disttest/message/NoOpCommand.java | 30 + .../qpid/disttest/message/OutputAttribute.java | 35 + .../disttest/message/ParticipantAttribute.java | 70 + .../message/ParticipantAttributeExtractor.java | 89 + .../qpid/disttest/message/ParticipantResult.java | 272 + .../message/ProducerParticipantResult.java | 100 + .../disttest/message/RegisterClientCommand.java | 43 + .../org/apache/qpid/disttest/message/Response.java | 80 + .../qpid/disttest/message/StartTestCommand.java | 29 + .../qpid/disttest/message/StopClientCommand.java | 28 + .../qpid/disttest/message/TearDownTestCommand.java | 29 + .../results/aggregation/AggregatedTestResult.java | 97 + .../disttest/results/aggregation/Aggregator.java | 49 + .../disttest/results/aggregation/ITestResult.java | 36 + .../aggregation/ParticipantResultAggregator.java | 143 + .../results/aggregation/TestResultAggregator.java | 106 + .../disttest/results/formatting/CSVFormater.java | 89 + .../CSVOrderParticipantResultComparator.java | 55 + .../main/java/org/apache/qpid/oldtopic/Config.java | 243 - .../java/org/apache/qpid/oldtopic/Listener.java | 141 - .../org/apache/qpid/oldtopic/MessageFactory.java | 153 - .../java/org/apache/qpid/oldtopic/Publisher.java | 178 - .../org/apache/qpid/ping/PingAsyncTestPerf.java | 323 - .../main/java/org/apache/qpid/ping/PingClient.java | 112 - .../org/apache/qpid/ping/PingDurableClient.java | 452 - .../org/apache/qpid/ping/PingLatencyTestPerf.java | 311 - .../org/apache/qpid/ping/PingSendOnlyClient.java | 93 - .../java/org/apache/qpid/ping/PingTestPerf.java | 281 - .../apache/qpid/requestreply/PingPongBouncer.java | 453 - .../apache/qpid/requestreply/PingPongProducer.java | 1818 --- .../apache/qpid/requestreply/PingPongTestPerf.java | 251 - .../main/java/org/apache/qpid/topic/Config.java | 326 - .../main/java/org/apache/qpid/topic/Listener.java | 303 - .../java/org/apache/qpid/topic/MessageFactory.java | 157 - .../main/java/org/apache/qpid/topic/Publisher.java | 186 - .../TopicWithSelectorsTransientVolumeTest.java | 344 - .../apache/qpid/topic/topicselectors.properties | 24 - .../src/main/resources/perftests.properties | 20 + .../apache/qpid/disttest/ArgumentParserTest.java | 96 + .../org/apache/qpid/disttest/ConfigFileHelper.java | 48 + .../java/org/apache/qpid/disttest/VisitorTest.java | 92 + .../disttest/client/ClientCommandVisitorTest.java | 108 + .../apache/qpid/disttest/client/ClientTest.java | 159 + .../disttest/client/ConsumerParticipantTest.java | 180 + .../qpid/disttest/client/MessageProviderTest.java | 107 + .../disttest/client/ParticipantExecutorTest.java | 183 + .../disttest/client/ParticipantRegistryTest.java | 55 + .../client/ParticipantResultFactoryTest.java | 183 + .../disttest/client/ParticipantTestHelper.java | 83 + .../disttest/client/ProducerParticipantTest.java | 219 + .../client/property/ListPropertyValueTest.java | 88 + .../client/property/PropertyValueFactoryTest.java | 73 + .../client/property/RandomPropertyValueTest.java | 76 + .../client/property/RangePropertyValueTest.java | 153 + .../client/property/SimplePropertyValueTest.java | 30 + .../disttest/controller/ClientRegistryTest.java | 99 + .../qpid/disttest/controller/ControllerTest.java | 198 + .../controller/ParticipatingClientsTest.java | 144 + .../qpid/disttest/controller/TestRunnerTest.java | 253 + .../controller/config/ClientConfigTest.java | 111 + .../controller/config/ConfigReaderTest.java | 113 + .../disttest/controller/config/ConfigTest.java | 56 + .../controller/config/ConfigTestUtils.java | 56 + .../controller/config/ConnectionConfigTest.java | 94 + .../controller/config/ConsumerConfigTest.java | 79 + .../controller/config/IterationValueTest.java | 78 + .../config/MessageProviderConfigTest.java | 51 + .../controller/config/ProducerConfigTest.java | 89 + .../controller/config/SessionConfigTest.java | 93 + .../disttest/controller/config/TestConfigTest.java | 113 + .../controller/config/TestInstanceTest.java | 102 + .../disttest/controller/config/sampleConfig.json | 72 + .../qpid/disttest/jms/JmsMessageAdaptorTest.java | 40 + .../qpid/disttest/message/JsonHandlerTest.java | 183 + .../disttest/message/ParticipantResultTest.java | 162 + .../results/aggregation/AggregatorTest.java | 61 + .../ParticipantResultAggregatorTest.java | 272 + .../aggregation/TestResultAggregatorTest.java | 152 + .../results/formatting/CSVFormaterTest.java | 144 + .../CSVOrderParticipantResultComparatorTest.java | 89 + .../disttest/results/formatting/expectedOutput.csv | 2 + .../disttest/DistributedTestSystemTestBase.java | 72 + .../systest/disttest/QpidQueueCreatorTest.java | 116 + .../qpid/systest/disttest/SystemTestConstants.java | 28 + .../clientonly/BasicDistributedClientTest.java | 186 + .../clientonly/ConsumerParticipantTest.java | 156 + .../disttest/clientonly/ControllerQueue.java | 90 + .../disttest/clientonly/DistributedClientTest.java | 323 + .../disttest/clientonly/MessageProviderTest.java | 119 + .../clientonly/ProducerParticipantTest.java | 132 + .../ControllerAndClientTest.java | 249 + .../controllerandclient/iteratingFeature.json | 63 + .../controllerandclient/produceClient.json | 41 + .../producerAndConsumerInSeparateClients.json | 55 + ...producerAndThreeConsumersInSeparateClients.json | 77 + .../controllerandclient/testWithTwoTests.json | 107 + .../controlleronly/DistributedControllerTest.java | 157 + .../controlleronly/distributedControllerTest.json | 17 + .../systest/disttest/endtoend/EndToEndTest.java | 95 + .../qpid/systest/disttest/endtoend/endtoend.json | 65 + .../systest/disttest/perftests.systests.properties | 26 + java/perftests/visualisation-jfc/build.xml | 142 + .../apache/qpid/disttest/charting/ChartType.java | 26 + .../qpid/disttest/charting/ChartingException.java | 46 + .../qpid/disttest/charting/ChartingUtil.java | 135 + .../charting/chartbuilder/BarChartBuilder.java | 47 + .../charting/chartbuilder/ChartBuilder.java | 30 + .../charting/chartbuilder/ChartBuilderFactory.java | 40 + .../charting/chartbuilder/DataPointCallback.java | 27 + .../chartbuilder/DataSetBasedChartBuilder.java | 68 + .../charting/chartbuilder/LineChartBuilder.java | 45 + .../charting/chartbuilder/SeriesBuilder.java | 133 + .../charting/definition/ChartingDefinition.java | 85 + .../definition/ChartingDefinitionCreator.java | 140 + .../charting/definition/SeriesDefinition.java | 50 + .../definition/SeriesDefinitionCreator.java | 60 + .../chartbuilder/ChartBuilderFactoryTest.java | 40 + .../charting/chartbuilder/SeriesBuilderTest.java | 90 + .../definition/ChartingDefinitionCreatorTest.java | 149 + .../definition/SeriesDefinitionCreatorTest.java | 113 + java/systests/build.xml | 6 +- java/systests/etc/bin/testclients.sh | 23 - .../etc/virtualhosts-systests-bdb-settings.xml | 6 +- .../etc/virtualhosts-systests-derby-settings.xml | 8 +- .../etc/virtualhosts-systests-firewall-2.xml | 4 +- .../etc/virtualhosts-systests-firewall-3.xml | 4 +- .../qpid/client/AsynchMessageListenerTest.java | 362 + .../org/apache/qpid/client/DispatcherTest.java | 233 - ...sageListenerMultiConsumerImmediatePrefetch.java | 44 - .../client/MessageListenerMultiConsumerTest.java | 252 - .../apache/qpid/client/MessageListenerTest.java | 258 - .../qpid/client/ResetMessageListenerTest.java | 228 - .../org/apache/qpid/client/SessionCreateTest.java | 7 +- .../org/apache/qpid/client/SynchReceiveTest.java | 133 + .../client/redelivered/RedeliveredMessageTest.java | 20 + .../org/apache/qpid/jms/xa/XAResourceTest.java | 17 +- .../qpid/management/jmx/ManagedQueueMBeanTest.java | 256 +- .../org/apache/qpid/ra/QpidRAConnectionTest.java | 89 + .../qpid/server/SupportedProtocolVersionsTest.java | 3 + .../exchange/MessagingTestConfigProperties.java | 300 - .../ReturnUnroutableMandatoryMessageTest.java | 2 +- .../logging/DerbyMessageStoreLoggingTest.java | 573 - .../logging/MemoryMessageStoreLoggingTest.java | 186 - .../server/logging/SubscriptionLoggingTest.java | 5 +- .../persistent/NoLocalAfterRecoveryTest.java | 78 +- .../qpid/server/queue/PriorityQueueTest.java | 100 + .../qpid/server/queue/ProducerFlowControlTest.java | 36 +- .../apache/qpid/server/store/SlowMessageStore.java | 70 +- .../qpid/server/store/SlowMessageStoreFactory.java | 37 + .../org/apache/qpid/test/client/CancelTest.java | 101 - .../ImmediateAndMandatoryPublishingTest.java | 98 +- .../qpid/test/client/QueueBrowserAutoAckTest.java | 28 +- .../test/client/timeouts/SyncWaitDelayTest.java | 2 +- .../apache/qpid/test/framework/AMQPPublisher.java | 54 - .../org/apache/qpid/test/framework/Assertion.java | 39 - .../apache/qpid/test/framework/AssertionBase.java | 66 - .../qpid/test/framework/BrokerLifecycleAware.java | 70 - .../apache/qpid/test/framework/CauseFailure.java | 42 - .../test/framework/CauseFailureUserPrompt.java | 63 - .../org/apache/qpid/test/framework/Circuit.java | 109 - .../org/apache/qpid/test/framework/CircuitEnd.java | 95 - .../apache/qpid/test/framework/CircuitEndBase.java | 156 - .../org/apache/qpid/test/framework/DropInTest.java | 51 - .../qpid/test/framework/ExceptionMonitor.java | 204 - .../qpid/test/framework/FrameworkBaseCase.java | 299 - .../qpid/test/framework/FrameworkTestContext.java | 48 - .../test/framework/LocalAMQPCircuitFactory.java | 173 - .../qpid/test/framework/LocalCircuitFactory.java | 320 - .../qpid/test/framework/MessageIdentityVector.java | 167 - .../apache/qpid/test/framework/MessageMonitor.java | 104 - .../framework/MessagingTestConfigProperties.java | 684 - .../test/framework/NotApplicableAssertion.java | 112 - .../org/apache/qpid/test/framework/Publisher.java | 74 - .../org/apache/qpid/test/framework/Receiver.java | 92 - .../apache/qpid/test/framework/TestCaseVector.java | 88 - .../qpid/test/framework/TestClientDetails.java | 86 - .../org/apache/qpid/test/framework/TestUtils.java | 200 - .../clocksynch/ClockSynchFailureException.java | 45 - .../framework/clocksynch/ClockSynchThread.java | 124 - .../framework/clocksynch/ClockSynchronizer.java | 69 - .../clocksynch/LocalClockSynchronizer.java | 73 - .../framework/clocksynch/UDPClockReference.java | 169 - .../framework/clocksynch/UDPClockSynchronizer.java | 468 - .../distributedcircuit/DistributedCircuitImpl.java | 472 - .../DistributedPublisherImpl.java | 94 - .../DistributedReceiverImpl.java | 94 - .../distributedcircuit/TestClientCircuitEnd.java | 333 - .../framework/distributedtesting/Coordinator.java | 546 - .../DistributedTestDecorator.java | 164 - .../distributedtesting/FanOutTestDecorator.java | 241 - .../distributedtesting/InteropTestDecorator.java | 210 - .../distributedtesting/OptOutTestCase.java | 69 - .../framework/distributedtesting/TestClient.java | 510 - .../TestClientControlledTest.java | 107 - .../test/framework/listeners/XMLTestListener.java | 414 - .../localcircuit/LocalAMQPPublisherImpl.java | 137 - .../framework/localcircuit/LocalCircuitImpl.java | 313 - .../framework/localcircuit/LocalPublisherImpl.java | 176 - .../framework/localcircuit/LocalReceiverImpl.java | 149 - .../org/apache/qpid/test/framework/package.html | 43 - .../framework/sequencers/BaseCircuitFactory.java | 136 - .../test/framework/sequencers/CircuitFactory.java | 101 - .../framework/sequencers/FanOutCircuitFactory.java | 200 - .../sequencers/InteropCircuitFactory.java | 154 - .../apache/qpid/test/unit/ack/AcknowledgeTest.java | 18 +- .../qpid/test/unit/basic/BytesMessageTest.java | 43 + .../apache/qpid/test/unit/basic/ReceiveTest.java | 82 - .../BrokerClosesClientConnectionTest.java | 17 + .../qpid/test/unit/close/CloseBeforeAckTest.java | 140 - .../test/unit/close/MessageConsumerCloseTest.java | 77 + .../qpid/test/unit/ct/DurableSubscriberTest.java | 19 +- .../test/unit/topic/DurableSubscriptionTest.java | 2 +- .../unit/transacted/TransactionTimeoutTest.java | 35 + .../org/apache/qpid/test/unit/xa/FaultTest.java | 2 +- .../org/apache/qpid/test/unit/xa/QueueTest.java | 6 +- .../org/apache/qpid/test/unit/xa/TopicTest.java | 72 +- .../org/apache/qpid/test/utils/JMXTestUtils.java | 10 +- .../apache/qpid/test/utils/QpidBrokerTestCase.java | 52 +- .../qpid/test/utils/SpawnedBrokerHolder.java | 2 +- java/test-profiles/CPPExcludes | 10 +- java/test-profiles/CPPPrefetchExcludes | 4 +- java/test-profiles/Excludes | 4 +- java/test-profiles/Java010Excludes | 3 + java/test-profiles/JavaBDBExcludes | 1 + java/test-profiles/JavaDerbyExcludes | 4 +- java/test-profiles/JavaExcludes | 4 +- java/test-profiles/JavaPre010Excludes | 16 +- java/test-profiles/JavaTransientExcludes | 13 +- java/test-profiles/java-bdb-spawn.0-10.testprofile | 2 +- java/test-profiles/java-bdb-spawn.0-8.testprofile | 6 +- .../test-profiles/java-bdb-spawn.0-9-1.testprofile | 6 +- java/test-profiles/java-bdb-spawn.0-9.testprofile | 6 +- java/test-profiles/java-bdb.0-10.testprofile | 2 +- java/test-profiles/java-bdb.0-8.testprofile | 6 +- java/test-profiles/java-bdb.0-9-1.testprofile | 6 +- java/test-profiles/java-bdb.0-9.testprofile | 6 +- java/test-profiles/java-dby-spawn.0-10.testprofile | 2 +- java/test-profiles/java-dby-spawn.0-8.testprofile | 6 +- .../test-profiles/java-dby-spawn.0-9-1.testprofile | 6 +- java/test-profiles/java-dby-spawn.0-9.testprofile | 6 +- java/test-profiles/java-dby.0-10.testprofile | 2 +- java/test-profiles/java-dby.0-8.testprofile | 6 +- java/test-profiles/java-dby.0-9-1.testprofile | 6 +- java/test-profiles/java-dby.0-9.testprofile | 6 +- java/test-profiles/java-mms-spawn.0-8.testprofile | 4 +- .../test-profiles/java-mms-spawn.0-9-1.testprofile | 4 +- java/test-profiles/java-mms-spawn.0-9.testprofile | 4 +- java/test-profiles/java-mms.0-8.testprofile | 4 +- java/test-profiles/java-mms.0-9-1.testprofile | 4 +- java/test-profiles/java-mms.0-9.testprofile | 4 +- .../python_tests/Java010PythonExcludes | 59 +- java/test-profiles/testprofile.defaults | 4 +- java/testkit/README.txt | 6 - java/testkit/bin/run_soak_client.sh | 70 - java/testkit/bin/soak_report.sh | 161 - java/testkit/build.xml | 27 - .../apache/qpid/testkit/soak/ResourceLeakTest.java | 180 - java/tools/bin/controller | 132 - java/tools/bin/jms-quick-perf-report | 137 + java/tools/bin/mercury-controller | 132 + java/tools/bin/mercury-start-consumers | 119 + java/tools/bin/mercury-start-producers | 136 + java/tools/bin/perf-report | 137 - java/tools/bin/start-consumers | 119 - java/tools/bin/start-producers | 136 - .../src/main/java/org/apache/qpid/tools/Clock.java | 2 + .../org/apache/qpid/tools/JVMArgConfiguration.java | 411 + .../java/org/apache/qpid/tools/LatencyTest.java | 349 - .../java/org/apache/qpid/tools/MercuryBase.java | 191 + .../qpid/tools/MercuryConsumerController.java | 231 + .../qpid/tools/MercuryProducerController.java | 210 + .../apache/qpid/tools/MercuryTestController.java | 450 + .../main/java/org/apache/qpid/tools/PerfBase.java | 226 - .../java/org/apache/qpid/tools/PerfConsumer.java | 325 - .../java/org/apache/qpid/tools/PerfProducer.java | 358 - .../org/apache/qpid/tools/PerfTestController.java | 442 - .../java/org/apache/qpid/tools/QpidReceive.java | 181 + .../main/java/org/apache/qpid/tools/QpidSend.java | 291 + .../org/apache/qpid/tools/TestConfiguration.java | 126 + .../java/org/apache/qpid/tools/TestParams.java | 214 - .../apache/qpid/tools/report/BasicReporter.java | 113 + .../apache/qpid/tools/report/MercuryReporter.java | 167 + .../org/apache/qpid/tools/report/Reporter.java | 40 + .../org/apache/qpid/tools/report/Statistics.java | 139 + 1335 files changed, 140291 insertions(+), 51206 deletions(-) create mode 100644 java/.gitignore create mode 100644 java/amqp-1-0-client-jms/build.xml create mode 100644 java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/Hello.java create mode 100644 java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/hello.properties create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/AmqpMessage.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/BytesMessage.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Connection.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionFactory.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionMetaData.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Destination.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/JavaSerializable.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MapMessage.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageConsumer.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageProducer.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ObjectMessage.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Queue.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueBrowser.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueConnection.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueReceiver.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSender.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSession.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Session.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/StreamMessage.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryDestination.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryQueue.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryTopic.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TextMessage.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Topic.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicConnection.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicPublisher.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSession.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSubscriber.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionMetaDataImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DestinationImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueConnectionImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSenderImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSessionImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryQueueImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryTopicImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicConnectionImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicPublisherImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSessionImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/NameParserImpl.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java create mode 100644 java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/ReadOnlyContext.java create mode 100644 java/amqp-1-0-client/build.xml create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/AcknowledgeMode.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Message.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Session.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Transaction.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransactionController.java create mode 100644 java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java create mode 100644 java/amqp-1-0-common/build.xml create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractDescribedTypeWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractListWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractMapWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryString.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteArrayWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteBufferWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeAssembler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DecimalConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DefaultDescribedTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DelegatingValueWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedType.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructorRegistry.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/Encoder.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedEightWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedFourWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedOneWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedSixteenWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedTwoWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntegerWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ListWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/MapWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHeaderHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/RestrictedTypeValueWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SimpleVariableWidthWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallIntConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallLongConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallUIntConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallULongConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolArrayWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UByteTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UIntTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ULongTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UShortTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedByteWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedIntegerWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedLongWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedShortWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueProducingProtocolHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthTypeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/WrapperTypeValueWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroListConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroUIntConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroULongConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQPProtocolHeaderHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameParsingError.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameTypeHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/OversizeFrameException.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrame.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrameHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLProtocolHeaderHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/TransportFrame.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/MessageAttributes.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoder.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoderImpl.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoder.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoderImpl.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPFrameTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesProcessor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CallbackHandlerSource.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CircularBytesBuffer.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEventListener.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionState.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/DeliveryStateHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ErrorHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameOutputHandler.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEventListener.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Node.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ProtocolHeaderTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkListener.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingSessionHalfEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpointImpl.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLFrameTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLTransport.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkListener.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingSessionHalfEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SequenceNumber.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionAttachment.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEventListener.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionHalfEndpoint.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionState.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/StateChangeListener.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/UnsettledTransfer.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/AmqpErrorException.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Binary.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DeliveryState.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DistributionMode.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/ErrorCondition.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/FrameBody.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/GlobalTxId.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/LifetimePolicy.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Outcome.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/RestrictedType.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/SaslFrameBody.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Section.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Source.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Symbol.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Target.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnCapability.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnId.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedByte.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedInteger.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedLong.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedShort.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/WrapperType.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/codec/AMQPDescribedTypeRegistry.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Accepted.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpSequence.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpValue.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ApplicationProperties.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Data.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnClose.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinks.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinksOrMessages.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoMessages.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeliveryAnnotations.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ExactSubjectFilter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Filter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Footer.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Header.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/JMSSelectorFilter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MatchingSubjectFilter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MessageAnnotations.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Modified.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/NoLocalFilter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Properties.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Received.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Rejected.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Released.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Source.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/StdDistMode.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Target.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusDurability.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusExpiryPolicy.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslChallenge.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslCode.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslInit.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslMechanisms.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslOutcome.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslResponse.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Coordinator.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declare.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declared.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Discharge.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionErrors.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionalState.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapabilities.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapability.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/AmqpError.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Attach.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Begin.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Close.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ConnectionError.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Detach.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Disposition.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/End.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Flow.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/LinkError.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Open.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ReceiverSettleMode.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Role.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SenderSettleMode.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SessionError.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Transfer.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenWriter.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferConstructor.java create mode 100644 java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferWriter.java delete mode 100755 java/bdbstore/bin/storeUpgrade.sh delete mode 100755 java/bdbstore/etc/scripts/bdbtest.sh delete mode 100644 java/bdbstore/src/main/java/BDBStoreUpgrade.log4j.xml delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AMQShortStringTB.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreFactory.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/BDBStoreUpgrade.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ContentTB.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/DatabaseVisitor.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/ExchangeTB.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/MessageContentKey.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/QueueEntryKey.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/StringMapBinding.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/UUIDTupleBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/entry/PreparedTransaction.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/entry/QueueEntryKey.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/entry/Xid.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/keys/MessageContentKey_4.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/keys/MessageContentKey_5.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/records/BindingRecord.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/records/ExchangeRecord.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/records/QueueRecord.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/ConfiguredObjectBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/ContentBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/MessageMetaDataBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/PreparedTransactionBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/QueueEntryBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/StringMapBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/UUIDTupleBinding.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/XidBinding.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/BindingTuple.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/BindingTupleBindingFactory.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/BindingTuple_4.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/MessageContentKeyTB_4.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/MessageContentKeyTB_5.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/MessageContentKeyTupleBindingFactory.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/MessageMetaDataTB_4.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/MessageMetaDataTB_5.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/MessageMetaDataTupleBindingFactory.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueEntryTB.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueTuple.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueTupleBindingFactory.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueTuple_4.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/QueueTuple_5.java delete mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuples/TupleBindingFactory.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractStoreUpgrade.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/CursorOperation.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/CursorTemplate.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/DatabaseCallable.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/DatabaseEntryCallback.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/DatabaseRunnable.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/DatabaseTemplate.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/StoreUpgrade.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4To5.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeInteractionHandler.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeInteractionResponse.java create mode 100644 java/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/upgrade/Upgrader.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/BDBMessageStoreConfigurationTest.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/tuple/ConfiguredObjectBindingTest.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/AbstractUpgradeTestCase.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/DatabaseTemplateTest.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom4to5Test.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgradeFrom5To6Test.java create mode 100644 java/bdbstore/src/test/java/org/apache/qpid/server/store/berkeleydb/upgrade/UpgraderTest.java delete mode 100644 java/bdbstore/src/test/resources/upgrade/bdbstore-to-upgrade/test-store/00000000.jdb create mode 100644 java/bdbstore/src/test/resources/upgrade/bdbstore-v4/test-store/00000000.jdb create mode 100644 java/bdbstore/src/test/resources/upgrade/bdbstore-v5/readme.txt create mode 100644 java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000000.jdb create mode 100644 java/bdbstore/src/test/resources/upgrade/bdbstore-v5/test-store/00000001.jdb delete mode 100644 java/broker-plugins/experimental/info/MANIFEST.MF delete mode 100644 java/broker-plugins/experimental/info/build.properties delete mode 100644 java/broker-plugins/experimental/info/build.xml delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Activator.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/AppInfo.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/Info.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/InfoService.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/InfoServiceImpl.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/SystemInfo.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/util/HttpPoster.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/util/IniFileReader.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/util/SoapClient.java delete mode 100644 java/broker-plugins/experimental/info/src/main/java/org/apache/qpid/info/util/XMLWriter.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/systest/InfoPluginTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/HttpPosterTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/InfoServiceImplTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/InfoServlet.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/InfoTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/IniFileReaderTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/SoapClientTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/SystemInfoTest.java delete mode 100644 java/broker-plugins/experimental/info/src/test/java/org/apache/qpid/info/test/XMLWriterTest.java delete mode 100644 java/broker/bin/create-example-ssl-stores.bat delete mode 100755 java/broker/bin/create-example-ssl-stores.sh create mode 100755 java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/Binding.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/ConfigurationChangeListener.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/ConfiguredObject.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/Consumer.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/Exchange.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/IllegalStateTransitionException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/LifetimePolicy.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/Publisher.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/Queue.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/State.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/Statistics.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/model/UUIDGenerator.java create mode 100755 java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Destination.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/QueueDestination.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingDestination.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingDestination.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryVisitor.java delete mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/AbstractMessageStore.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectHelper.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/ConfiguredObjectRecord.java delete mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/DerbyMessageStore.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/Event.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/EventListener.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/EventManager.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/MemoryMessageStoreFactory.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreConstants.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/MessageStoreFactory.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/NullMessageStore.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/OperationalLoggingListener.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/State.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/StateManager.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/StoreFuture.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/Transaction.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStore.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/store/derby/DerbyMessageStoreFactory.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/AlreadyKnownDtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/DistributedTransaction.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/DtxBranch.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/DtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/DtxNotSelectedException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/DtxRegistry.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/IncorrectDtxStateException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/JoinAndResumeDtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/NotAssociatedDtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/RollbackOnlyDtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/SuspendAndFailDtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/TimeoutDtxException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/txn/UnknownDtxBranchException.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/util/MapJsonSerializer.java create mode 100644 java/broker/src/main/java/org/apache/qpid/server/virtualhost/State.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/AMQChannelTest.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/queue/PriorityQueueListTest.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/DurableConfigurationStoreTest.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/EventManagerTest.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/OperationalLoggingListenerTest.java delete mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/SkeletonMessageStore.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/StateManagerTest.java delete mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/TestMemoryMessageStore.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/store/TestableMemoryMessageStoreFactory.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/transport/ServerSessionTest.java create mode 100644 java/broker/src/test/java/org/apache/qpid/server/util/MapJsonSerializerTest.java create mode 100644 java/client/src/test/java/org/apache/qpid/jndi/JNDITest.properties create mode 100644 java/client/src/test/java/org/apache/qpid/jndi/PropertiesFileInitialContextFactoryTest.java create mode 100644 java/client/src/test/java/org/apache/qpid/jndi/hello.properties delete mode 100644 java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDIPropertyFileTest.java delete mode 100644 java/client/src/test/java/org/apache/qpid/test/unit/jndi/JNDITest.properties delete mode 100644 java/integrationtests/README.txt delete mode 100755 java/integrationtests/bin/interoptests.py delete mode 100644 java/integrationtests/build.xml delete mode 100644 java/integrationtests/docs/RunningSustainedTests.txt delete mode 100644 java/integrationtests/jar-with-dependencies.xml delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase1DummyRun.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase2BasicP2P.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase4P2PMessageSize.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/clienttestcases/TestCase5PubSubMessageSize.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase1DummyRun.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase2BasicP2P.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase3BasicPubSub.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase4P2PMessageSize.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/interop/testcases/InteropTestCase5PubSubMessageSize.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedClientTestCase.java delete mode 100644 java/integrationtests/src/main/java/org/apache/qpid/sustained/SustainedTestCase.java delete mode 100644 java/integrationtests/src/resources/sustained-log4j.xml delete mode 100644 java/jca/.gitignore create mode 100644 java/jca/example/README-EXAMPLE.txt create mode 100644 java/jca/example/README-GERONIMO.txt create mode 100644 java/jca/example/README-GLASSFISH.txt create mode 100644 java/jca/example/README-JBOSS.txt create mode 100644 java/jca/example/README-JBOSS7.txt delete mode 100644 java/jca/example/README.txt create mode 100644 java/jca/example/build-glassfish-properties.xml create mode 100644 java/jca/example/build-jboss7-properties.xml create mode 100644 java/jca/example/conf/glassfish-ejb-jar.xml create mode 100644 java/jca/example/conf/glassfish-resources.xml create mode 100644 java/jca/example/conf/glassfish-web.xml create mode 100644 java/jca/example/conf/jboss-ejb-client.properties create mode 100644 java/jca/example/conf/qpid-standalone.xml create mode 100644 java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidRequestResponseServlet.java create mode 100644 java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidExceptionHandler.java create mode 100644 java/jca/src/main/java/org/apache/qpid/ra/tm/GlassfishTransactionManagerLocator.java create mode 100644 java/jca/src/main/java/org/apache/qpid/ra/tm/WLSTransactionManagerLocator.java create mode 100644 java/jca/src/test/java/org/apache/qpid/ra/QpidActivationSpecTest.java create mode 100644 java/jca/src/test/java/org/apache/qpid/ra/QpidResourceAdapterTest.java delete mode 100644 java/junit-toolkit/build.xml delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/DefaultThreadFactory.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/PossibleDeadlockException.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/TestRunnable.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestCoordinator.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/ThreadTestExample.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/concurrency/package.html delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestCase.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/AsymptoticTestDecorator.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BaseThrottle.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/BatchedThrottle.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/DurationTestDecorator.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/InstrumentedTest.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/NullResultPrinter.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ParameterVariationTestDecorator.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ScaledTestDecorator.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskAware.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SetupTaskHandler.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/ShutdownHookable.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/SleepThrottle.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestResult.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TKTestRunner.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestRunnerImprovedErrorHandling.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TestThreadAware.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/Throttle.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingController.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/TimingControllerAware.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/WrappedSuiteTestDecorator.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/CSVTestListener.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/ConsoleTestListener.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/TKTestListener.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/XMLTestListener.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/listeners/package.html delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/package.html delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/CommandLineParser.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ContextualProperties.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/MathUtils.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/ParsedProperties.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/SizeOf.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/StackQueue.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestContextProperties.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/TestUtils.java delete mode 100644 java/junit-toolkit/src/main/org/apache/qpid/junit/extensions/util/package.html create mode 100644 java/lib/gson-2.0.jar create mode 100644 java/lib/jackson-core-asl-1.9.0.jar create mode 100644 java/lib/jackson-mapper-asl-1.9.0.jar delete mode 100644 java/lib/jetty-6.1.14.jar delete mode 100644 java/lib/jetty-servlet-tester-6.1.14.jar delete mode 100644 java/lib/jetty-util-6.1.14.jar create mode 100644 java/lib/mockito-all-1.9.0.jar delete mode 100644 java/lib/org.apache.felix.framework-2.0.5.jar create mode 100644 java/lib/org.apache.felix.main-2.0.5.jar create mode 100644 java/lib/poms/jackson-core-asl-1.9.0.xml create mode 100644 java/lib/poms/jackson-mapper-asl-1.9.0.xml delete mode 100644 java/lib/poms/org.apache.felix.framework-2.0.5.xml create mode 100644 java/lib/poms/org.apache.felix.main-2.0.5.xml delete mode 100644 java/lib/poms/org.osgi.core-1.0.0.xml delete mode 100644 java/lib/servlet-api.jar delete mode 100644 java/perftests/RunningPerformanceTests.txt delete mode 100755 java/perftests/bin/monitoring/monitor-broker.sh delete mode 100755 java/perftests/bin/monitoring/runTests.sh delete mode 100755 java/perftests/bin/monitoring/stop-monitored-broker.sh delete mode 100755 java/perftests/bin/processing/process.sh delete mode 100755 java/perftests/bin/processing/processAll.sh delete mode 100755 java/perftests/bin/processing/processTests.py delete mode 100755 java/perftests/bin/run_many.sh delete mode 100755 java/perftests/bin/topicListener.sh delete mode 100755 java/perftests/bin/topicPublisher.sh delete mode 100644 java/perftests/dist-zip.xml create mode 100644 java/perftests/etc/chartdefs/AcknowledgementModesAutoAck.chartdef create mode 100644 java/perftests/etc/chartdefs/AcknowledgementModesTransacted.chartdef create mode 100644 java/perftests/etc/chartdefs/BatchSize.chartdef create mode 100644 java/perftests/etc/chartdefs/MessageSizeNonPersistent.chartdef create mode 100644 java/perftests/etc/chartdefs/MessageSizePersistent.chartdef create mode 100644 java/perftests/etc/chartdefs/QueueTypes.chartdef create mode 100644 java/perftests/etc/chartdefs/VaryingNumberOfConsumers.chartdef create mode 100644 java/perftests/etc/chartdefs/VaryingNumberOfProducers.chartdef delete mode 100644 java/perftests/etc/jndi/activemq.properties delete mode 100644 java/perftests/etc/jndi/failovertest.properties delete mode 100644 java/perftests/etc/jndi/perftests.properties delete mode 100644 java/perftests/etc/jndi/swiftmq.properties create mode 100644 java/perftests/etc/log4j.properties create mode 100644 java/perftests/etc/perftests-jndi.properties delete mode 100644 java/perftests/etc/perftests.log4j delete mode 100755 java/perftests/etc/scripts/CTQ-Qpid-1.sh delete mode 100755 java/perftests/etc/scripts/CTQ-Qpid-2.sh delete mode 100755 java/perftests/etc/scripts/CTQ-Qpid-3.sh delete mode 100755 java/perftests/etc/scripts/CTQ-Qpid-4.sh delete mode 100755 java/perftests/etc/scripts/CTQ-Qpid-5.sh delete mode 100755 java/perftests/etc/scripts/CTQ-Qpid-6.sh delete mode 100755 java/perftests/etc/scripts/Connections.sh delete mode 100755 java/perftests/etc/scripts/JobQueue.sh delete mode 100755 java/perftests/etc/scripts/Latency.sh delete mode 100755 java/perftests/etc/scripts/MessageSize.sh delete mode 100755 java/perftests/etc/scripts/PT-Qpid-13.sh delete mode 100755 java/perftests/etc/scripts/PT-Qpid-14.sh delete mode 100755 java/perftests/etc/scripts/Reliability.sh delete mode 100755 java/perftests/etc/scripts/RunAll.sh delete mode 100755 java/perftests/etc/scripts/RunCore.sh delete mode 100644 java/perftests/etc/scripts/Test-ActiveMQ.sh delete mode 100644 java/perftests/etc/scripts/Test-SwiftMQ.sh delete mode 100755 java/perftests/etc/scripts/Throughput.sh delete mode 100755 java/perftests/etc/scripts/drainBroker.sh delete mode 100755 java/perftests/etc/scripts/extractResults.sh delete mode 100755 java/perftests/etc/scripts/extractThroughputResults.sh delete mode 100755 java/perftests/etc/scripts/fillBroker.sh delete mode 100755 java/perftests/etc/scripts/sendAndWaitClient.sh delete mode 100755 java/perftests/etc/scripts/testWithPreFill.sh create mode 100644 java/perftests/etc/testdefs/short/AcknowledgementModes.json create mode 100644 java/perftests/etc/testdefs/short/BatchSize.json create mode 100644 java/perftests/etc/testdefs/short/MessageSize.json create mode 100644 java/perftests/etc/testdefs/short/QueueTypes.json create mode 100644 java/perftests/etc/testdefs/short/VaryingNumberOfParticipants.json create mode 100644 java/perftests/etc/testdefs/standard/AcknowledgementModes.json create mode 100644 java/perftests/etc/testdefs/standard/BatchSize.json create mode 100644 java/perftests/etc/testdefs/standard/MessageSize.json create mode 100644 java/perftests/etc/testdefs/standard/QueueTypes.json create mode 100644 java/perftests/etc/testdefs/standard/QueuesWithSelectors.json create mode 100644 java/perftests/etc/testdefs/standard/VaryingNumberOfParticipants.json create mode 100644 java/perftests/example/PQBT-AA-Qpid-01.json create mode 100644 java/perftests/example/TQBT-TX-Qpid-01.json create mode 100644 java/perftests/example/brokerconfig/log4j.xml create mode 100644 java/perftests/example/brokerconfig/passwd create mode 100644 java/perftests/example/brokerconfig/virtualhosts.xml create mode 100644 java/perftests/example/config-one-test.json create mode 100644 java/perftests/example/config-stress-testing-manyp-c1-with-psfc.json create mode 100644 java/perftests/example/config-stress-testing.json create mode 100644 java/perftests/example/config-two-tests.json create mode 100644 java/perftests/example/log4j-client.properties create mode 100644 java/perftests/example/log4j.properties create mode 100644 java/perftests/example/perftests-jndi.properties create mode 100755 java/perftests/example/run-client.sh create mode 100755 java/perftests/example/run.sh delete mode 100644 java/perftests/generate-scripts delete mode 100644 java/perftests/jar-with-dependencies.xml delete mode 100644 java/perftests/scripts.xml delete mode 100644 java/perftests/src/main/java/org/apache/qpid/client/message/TestMessageFactory.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/config/AMQConnectionFactoryInitialiser.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/config/AbstractConfig.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/config/ConnectionFactoryInitialiser.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/config/Connector.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/config/ConnectorConfig.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/config/JBossConnectionFactoryInitialiser.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/AbstractRunner.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/ArgumentParser.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/ClientRunner.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/ControllerRunner.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/DistributedTestConstants.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/DistributedTestException.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/Visitor.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/Client.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ClientCommandVisitor.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ClientState.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ConsumerParticipant.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/MessageProvider.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/Participant.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutor.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutorRegistry.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantResultFactory.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertySupport.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertyValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/ListPropertyValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/NumericGeneratedPropertySupport.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValueFactory.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RandomPropertyValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RangePropertyValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/client/property/SimplePropertyValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandForClient.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandListener.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/Controller.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/ParticipatingClients.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestResult.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunner.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunnerFactory.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ClientConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/Config.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConfigReader.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConnectionConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConsumerConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/IterationValue.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/MessageProviderConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ParticipantConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ProducerConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/QueueConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/SessionConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/TestConfig.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/TestInstance.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/jms/ClientJmsDelegate.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/jms/ControllerJmsDelegate.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/jms/JmsMessageAdaptor.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/jms/QpidQueueCreator.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/jms/QueueCreator.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/json/JsonHandler.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/json/PropertyValueAdapter.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/Command.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CommandType.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/ConsumerParticipantResult.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConnectionCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateConsumerCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateMessageProviderCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateParticpantCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateProducerCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateResponderCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/CreateSessionCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/NoOpCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/OutputAttribute.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttribute.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantAttributeExtractor.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/ParticipantResult.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/ProducerParticipantResult.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/RegisterClientCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/Response.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/StartTestCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/StopClientCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/message/TearDownTestCommand.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/AggregatedTestResult.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/Aggregator.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ITestResult.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregator.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregator.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVFormater.java create mode 100644 java/perftests/src/main/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparator.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/oldtopic/Config.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/oldtopic/Listener.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/oldtopic/MessageFactory.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/oldtopic/Publisher.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/ping/PingAsyncTestPerf.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/ping/PingClient.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/ping/PingDurableClient.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/ping/PingLatencyTestPerf.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/ping/PingSendOnlyClient.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/ping/PingTestPerf.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongBouncer.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongProducer.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/requestreply/PingPongTestPerf.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/topic/Config.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/topic/Listener.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/topic/MessageFactory.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/topic/Publisher.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/topic/TopicWithSelectorsTransientVolumeTest.java delete mode 100644 java/perftests/src/main/java/org/apache/qpid/topic/topicselectors.properties create mode 100644 java/perftests/src/main/resources/perftests.properties create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/ArgumentParserTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/ConfigFileHelper.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/VisitorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientCommandVisitorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ClientTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ConsumerParticipantTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/MessageProviderTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantExecutorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantRegistryTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantResultFactoryTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ParticipantTestHelper.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/ProducerParticipantTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/property/ListPropertyValueTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/property/PropertyValueFactoryTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RandomPropertyValueTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/property/RangePropertyValueTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/client/property/SimplePropertyValueTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/ClientRegistryTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/ControllerTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/ParticipatingClientsTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/TestRunnerTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ClientConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigReaderTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConfigTestUtils.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConnectionConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ConsumerConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/IterationValueTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/MessageProviderConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/ProducerConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/SessionConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestConfigTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/TestInstanceTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/controller/config/sampleConfig.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/jms/JmsMessageAdaptorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/message/JsonHandlerTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/message/ParticipantResultTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/AggregatorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/ParticipantResultAggregatorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/results/aggregation/TestResultAggregatorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVFormaterTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/CSVOrderParticipantResultComparatorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/disttest/results/formatting/expectedOutput.csv create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/DistributedTestSystemTestBase.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/QpidQueueCreatorTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/SystemTestConstants.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/clientonly/BasicDistributedClientTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/clientonly/ConsumerParticipantTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/clientonly/ControllerQueue.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/clientonly/DistributedClientTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/clientonly/MessageProviderTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/clientonly/ProducerParticipantTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controllerandclient/ControllerAndClientTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controllerandclient/iteratingFeature.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controllerandclient/produceClient.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controllerandclient/producerAndConsumerInSeparateClients.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controllerandclient/producerAndThreeConsumersInSeparateClients.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controllerandclient/testWithTwoTests.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controlleronly/DistributedControllerTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/controlleronly/distributedControllerTest.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/EndToEndTest.java create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/endtoend/endtoend.json create mode 100644 java/perftests/src/test/java/org/apache/qpid/systest/disttest/perftests.systests.properties create mode 100644 java/perftests/visualisation-jfc/build.xml create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartType.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingException.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/ChartingUtil.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/BarChartBuilder.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilder.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactory.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/DataPointCallback.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/DataSetBasedChartBuilder.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/LineChartBuilder.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesBuilder.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinition.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreator.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinition.java create mode 100644 java/perftests/visualisation-jfc/src/main/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreator.java create mode 100644 java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/ChartBuilderFactoryTest.java create mode 100644 java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/chartbuilder/SeriesBuilderTest.java create mode 100644 java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/ChartingDefinitionCreatorTest.java create mode 100644 java/perftests/visualisation-jfc/src/test/java/org/apache/qpid/disttest/charting/definition/SeriesDefinitionCreatorTest.java delete mode 100755 java/systests/etc/bin/testclients.sh create mode 100644 java/systests/src/main/java/org/apache/qpid/client/AsynchMessageListenerTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/client/DispatcherTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/client/MessageListenerMultiConsumerImmediatePrefetch.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/client/MessageListenerTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/client/ResetMessageListenerTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/client/SynchReceiveTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/ra/QpidRAConnectionTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/exchange/MessagingTestConfigProperties.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/logging/DerbyMessageStoreLoggingTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/server/logging/MemoryMessageStoreLoggingTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/server/store/SlowMessageStoreFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/client/CancelTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/AMQPPublisher.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Assertion.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/AssertionBase.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/BrokerLifecycleAware.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/CauseFailure.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/CauseFailureUserPrompt.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Circuit.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEnd.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/CircuitEndBase.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/DropInTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/ExceptionMonitor.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkBaseCase.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/FrameworkTestContext.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/LocalAMQPCircuitFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/MessageIdentityVector.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/MessageMonitor.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/MessagingTestConfigProperties.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/NotApplicableAssertion.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Publisher.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/Receiver.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/TestCaseVector.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/TestClientDetails.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/TestUtils.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchFailureException.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchThread.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/ClockSynchronizer.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/LocalClockSynchronizer.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/UDPClockReference.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/clocksynch/UDPClockSynchronizer.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedCircuitImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedPublisherImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/DistributedReceiverImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedcircuit/TestClientCircuitEnd.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/Coordinator.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/DistributedTestDecorator.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/FanOutTestDecorator.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/InteropTestDecorator.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/OptOutTestCase.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClient.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/distributedtesting/TestClientControlledTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/listeners/XMLTestListener.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalAMQPPublisherImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalCircuitImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalPublisherImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/localcircuit/LocalReceiverImpl.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/package.html delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/BaseCircuitFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/CircuitFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/FanOutCircuitFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/framework/sequencers/InteropCircuitFactory.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/unit/basic/ReceiveTest.java delete mode 100644 java/systests/src/main/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java create mode 100644 java/systests/src/main/java/org/apache/qpid/test/unit/close/MessageConsumerCloseTest.java delete mode 100644 java/testkit/README.txt delete mode 100644 java/testkit/bin/run_soak_client.sh delete mode 100644 java/testkit/bin/soak_report.sh delete mode 100644 java/testkit/build.xml delete mode 100644 java/testkit/src/main/java/org/apache/qpid/testkit/soak/ResourceLeakTest.java delete mode 100644 java/tools/bin/controller create mode 100755 java/tools/bin/jms-quick-perf-report create mode 100644 java/tools/bin/mercury-controller create mode 100644 java/tools/bin/mercury-start-consumers create mode 100644 java/tools/bin/mercury-start-producers delete mode 100755 java/tools/bin/perf-report delete mode 100644 java/tools/bin/start-consumers delete mode 100644 java/tools/bin/start-producers create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/JVMArgConfiguration.java delete mode 100644 java/tools/src/main/java/org/apache/qpid/tools/LatencyTest.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/MercuryBase.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/MercuryConsumerController.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/MercuryProducerController.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/MercuryTestController.java delete mode 100644 java/tools/src/main/java/org/apache/qpid/tools/PerfBase.java delete mode 100644 java/tools/src/main/java/org/apache/qpid/tools/PerfConsumer.java delete mode 100644 java/tools/src/main/java/org/apache/qpid/tools/PerfProducer.java delete mode 100644 java/tools/src/main/java/org/apache/qpid/tools/PerfTestController.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/QpidReceive.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/QpidSend.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/TestConfiguration.java delete mode 100644 java/tools/src/main/java/org/apache/qpid/tools/TestParams.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/report/BasicReporter.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/report/MercuryReporter.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/report/Reporter.java create mode 100644 java/tools/src/main/java/org/apache/qpid/tools/report/Statistics.java (limited to 'java') diff --git a/java/.gitignore b/java/.gitignore new file mode 100644 index 0000000000..36097e3820 --- /dev/null +++ b/java/.gitignore @@ -0,0 +1,2 @@ +*.swp +eclipse-projects/* diff --git a/java/amqp-1-0-client-jms/build.xml b/java/amqp-1-0-client-jms/build.xml new file mode 100644 index 0000000000..4a685d7106 --- /dev/null +++ b/java/amqp-1-0-client-jms/build.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/Hello.java b/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/Hello.java new file mode 100644 index 0000000000..61317e7f37 --- /dev/null +++ b/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/Hello.java @@ -0,0 +1,178 @@ +/* + * + * 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.amqp_1_0.jms.example; + +import javax.jms.*; +import javax.naming.Context; +import javax.naming.InitialContext; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Map; +import java.util.Properties; + + +public class Hello +{ + + public Hello() + { + } + + public static void main(String[] args) + { + try + { + Class.forName("org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory"); + + Hashtable env = new Hashtable(); + env.put("java.naming.provider.url", "hello.properties"); + env.put("java.naming.factory.initial", "org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory"); + + Context context = new InitialContext(env); + + ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("localhost"); + Connection connection = connectionFactory.createConnection(); + + Session producersession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Queue queue = (Queue) context.lookup("queue"); + + + Session consumerSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer messageConsumer = consumerSession.createConsumer(queue, "hello='true' and 7"); + + messageConsumer.setMessageListener(new MessageListener() + { + public void onMessage(final Message message) + { + try + { + + if(message instanceof TextMessage) + { + System.out.println("Received text Message:"); + System.out.println("======================"); + System.out.println(((TextMessage) message).getText()); + } + else if(message instanceof MapMessage) + { + System.out.println("Received Map Message:"); + System.out.println("====================="); + + + MapMessage mapmessage = (MapMessage) message; + + Enumeration names = mapmessage.getMapNames(); + + while(names.hasMoreElements()) + { + String name = (String) names.nextElement(); + System.out.println(name + " -> " + mapmessage.getObject(name)); + } + + } + else if(message instanceof BytesMessage) + { + System.out.println("Received Bytes Message:"); + System.out.println("======================="); + System.out.println(((BytesMessage) message).readUTF()); + } + else if(message instanceof StreamMessage) + { + System.out.println("Received Stream Message:"); + System.out.println("========================"); + StreamMessage streamMessage = (StreamMessage)message; + Object o = streamMessage.readObject(); + System.out.println(o.getClass().getName() + ": " + o); + o = streamMessage.readObject(); + System.out.println(o.getClass().getName() + ": " + o); + o = streamMessage.readObject(); + System.out.println(o.getClass().getName() + ": " + o); + + } + else if(message instanceof ObjectMessage) + { + System.out.println("Received Object Message:"); + System.out.println("========================"); + ObjectMessage objectMessage = (ObjectMessage)message; + Object o = objectMessage.getObject(); + System.out.println(o.getClass().getName() + ": " + o); + } + else + { + System.out.println("Received Message " + message.getClass().getName()); + } + } + catch (JMSException e) + { + e.printStackTrace(); //TODO + } + + } + }); + + connection.start(); + + + MessageProducer messageProducer = producersession.createProducer(queue); + TextMessage message = producersession.createTextMessage("Hello world!"); + message.setJMSType("Hello"); + message.setStringProperty("hello","true"); + messageProducer.send(message); + /* + MapMessage mapmessage = producersession.createMapMessage(); + mapmessage.setBoolean("mybool", true); + mapmessage.setString("mystring", "hello"); + mapmessage.setLong("mylong", -25L); + + + messageProducer.send(mapmessage); + + BytesMessage bytesMessage = producersession.createBytesMessage(); + bytesMessage.writeUTF("This is a bytes message"); + + messageProducer.send(bytesMessage); + + ObjectMessage objectMessage = producersession.createObjectMessage(); + objectMessage.setObject(new Double("3.14159265358979323846264338327950288")); + + messageProducer.send(objectMessage); + +/* StreamMessage streamMessage = producersession.createStreamMessage(); + streamMessage.writeBoolean(true); + streamMessage.writeLong(18031974L); + streamMessage.writeString("this is a stream Message"); + streamMessage.writeChar('£'); + messageProducer.send(streamMessage); +*/ + Thread.sleep(50000L); + + connection.close(); + context.close(); + } + catch (Exception exp) + { + exp.printStackTrace(); + } + } +} diff --git a/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/hello.properties b/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/hello.properties new file mode 100644 index 0000000000..930c2c15cc --- /dev/null +++ b/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/hello.properties @@ -0,0 +1,28 @@ +# +# 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. +# +java.naming.factory.initial = org.apache.qpid.amqp_1_0.jms.jndi.PropertiesFileInitialContextFactory + +# register some connection factories +# connectionfactory.[jndiname] = [ConnectionURL] +connectionfactory.localhost = http://guest:guest@localhost/test?cliendId='test-client' + + +# Register an AMQP destination in JNDI +# destination.[jniName] = [Address Format] +queue.queue = queue diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/AmqpMessage.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/AmqpMessage.java new file mode 100644 index 0000000000..de42b36ef2 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/AmqpMessage.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.amqp_1_0.jms; + +import org.apache.qpid.amqp_1_0.type.Section; + +import java.util.ListIterator; + +public interface AmqpMessage extends Message +{ + int getSectionCount(); + + Section getSection(int position); + + ListIterator
sectionIterator(); +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/BytesMessage.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/BytesMessage.java new file mode 100644 index 0000000000..3475319fe4 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/BytesMessage.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface BytesMessage extends Message, javax.jms.BytesMessage +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Connection.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Connection.java new file mode 100644 index 0000000000..97447917f6 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Connection.java @@ -0,0 +1,37 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; + + +public interface Connection extends javax.jms.Connection +{ + + ConnectionMetaData getMetaData() throws JMSException; + + Session createSession(boolean transacted, int acknowledgeMode) throws JMSException; + + Session createSession(Session.AcknowledgeMode acknowledgeMode) throws JMSException; + + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionFactory.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionFactory.java new file mode 100644 index 0000000000..752993b229 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionFactory.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.amqp_1_0.jms; + + +import javax.jms.JMSException; + +public interface ConnectionFactory extends javax.jms.ConnectionFactory +{ + Connection createConnection() throws JMSException; + + Connection createConnection(String username, String password) throws JMSException; +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionMetaData.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionMetaData.java new file mode 100644 index 0000000000..3802d6e416 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionMetaData.java @@ -0,0 +1,28 @@ +/* + * 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.amqp_1_0.jms; + +public interface ConnectionMetaData extends javax.jms.ConnectionMetaData +{ + int getAMQPMajorVersion(); + + int getAMQPMinorVersion(); + + int getAMQPRevisionVersion(); +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Destination.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Destination.java new file mode 100644 index 0000000000..0b467b3c99 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Destination.java @@ -0,0 +1,28 @@ +/* + * + * 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.amqp_1_0.jms; + +public interface Destination extends javax.jms.Destination +{ + public String getAddress(); + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/JavaSerializable.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/JavaSerializable.java new file mode 100644 index 0000000000..0c9179bc2b --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/JavaSerializable.java @@ -0,0 +1,24 @@ +/* + * 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.amqp_1_0.jms; + +public interface JavaSerializable +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MapMessage.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MapMessage.java new file mode 100644 index 0000000000..81754ecc93 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MapMessage.java @@ -0,0 +1,37 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; +import java.util.Set; + +public interface MapMessage extends Message, javax.jms.MapMessage +{ + public Object get(Object key) throws JMSException; + + public Object put(Object key, Object val) throws JMSException; + + public boolean itemExists(Object key) throws JMSException; + + Set keySet() throws JMSException; + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java new file mode 100644 index 0000000000..1481c54ee1 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java @@ -0,0 +1,178 @@ +/* + * + * 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.amqp_1_0.jms; + +import org.apache.qpid.amqp_1_0.messaging.MessageAttributes; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedByte; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.UnsignedShort; + +import javax.jms.JMSException; +import java.util.Date; +import java.util.List; +import java.util.Map; + + +public interface Message extends javax.jms.Message +{ + + Destination getJMSReplyTo() throws JMSException; + + Destination getJMSDestination() throws JMSException; + + // properties can be keyed by any valid apache.qpid.amqp_1_0 datatype, not just strings + + boolean propertyExists(Object name) throws JMSException; + + boolean getBooleanProperty(Object name) throws JMSException; + + byte getByteProperty(Object name) throws JMSException; + + short getShortProperty(Object name) throws JMSException; + + int getIntProperty(Object name) throws JMSException; + + long getLongProperty(Object name) throws JMSException; + + float getFloatProperty(Object name) throws JMSException; + + double getDoubleProperty(Object name) throws JMSException; + + String getStringProperty(Object name) throws JMSException; + + Object getObjectProperty(Object name) throws JMSException; + + // apache.qpid.amqp_1_0 allows for lists, maps, and unsigned integral data types + + List getListProperty(Object name) throws JMSException; + + Map getMapProperty(Object name) throws JMSException; + + UnsignedByte getUnsignedByteProperty(Object name) throws JMSException; + + UnsignedShort getUnsignedShortProperty(Object name) throws JMSException; + + UnsignedInteger getUnsignedIntProperty(Object name) throws JMSException; + + UnsignedLong getUnsignedLongProperty(Object name) throws JMSException; + + // properties can be keyed by any valid apache.qpid.amqp_1_0 datatype, not just strings + + void setBooleanProperty(Object name, boolean b) throws JMSException; + + void setByteProperty(Object name, byte b) throws JMSException; + + void setShortProperty(Object name, short i) throws JMSException; + + void setIntProperty(Object name, int i) throws JMSException; + + void setLongProperty(Object name, long l) throws JMSException; + + void setFloatProperty(Object name, float v) throws JMSException; + + void setDoubleProperty(Object name, double v) throws JMSException; + + void setStringProperty(Object name, String s1) throws JMSException; + + void setObjectProperty(Object name, Object o) throws JMSException; + + // apache.qpid.amqp_1_0 allows for lists, maps, and unsigned integral data types + + void setListProperty(Object name, List list) throws JMSException; + + void setMapProperty(Object name, Map map) throws JMSException; + + void setUnsignedByteProperty(Object name, UnsignedByte b) throws JMSException; + + void setUnsignedShortProperty(Object name, UnsignedShort s) throws JMSException; + + void setUnsignedIntProperty(Object name, UnsignedInteger i) throws JMSException; + + void setUnsignedLongProperty(Object name, UnsignedLong l) throws JMSException; + + // delegation accessors for Header section + + UnsignedInteger getDeliveryFailures(); + + void setDeliveryFailures(UnsignedInteger failures); + + MessageAttributes getHeaderMessageAttrs(); + + void setHeaderMessageAttrs(MessageAttributes messageAttrs); + + MessageAttributes getHeaderDeliveryAttrs(); + + void setHeaderDeliveryAttrs(MessageAttributes deliveryAttrs); + + Boolean getDurable(); + + void setDurable(Boolean durable); + + UnsignedByte getPriority(); + + void setPriority(UnsignedByte priority); + + Date getTransmitTime(); + + void setTransmitTime(Date transmitTime); + + UnsignedInteger getTtl(); + + void setTtl(UnsignedInteger ttl); + + UnsignedInteger getFormerAcquirers(); + + void setFormerAcquirers(UnsignedInteger formerAcquirers); + + // delegation accessors for Properties section + + Object getMessageId(); + + void setMessageId(Object messageId); + + Binary getUserId(); + + void setUserId(Binary userId); + + String getTo(); + + void setTo(String to); + + String getSubject(); + + void setSubject(String subject); + + String getReplyTo(); + + void setReplyTo(String replyTo); + + Object getCorrelationId(); + + void setCorrelationId(Binary correlationId); + + Symbol getContentType(); + + void setContentType(Symbol contentType); +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageConsumer.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageConsumer.java new file mode 100644 index 0000000000..fe235f098f --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageConsumer.java @@ -0,0 +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.amqp_1_0.jms; + +import javax.jms.JMSException; + + +public interface MessageConsumer extends javax.jms.MessageConsumer +{ + + Message receive() throws JMSException; + + Message receive(long l) throws JMSException; + + Message receiveNoWait() throws JMSException; + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageProducer.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageProducer.java new file mode 100644 index 0000000000..98987c2409 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageProducer.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.amqp_1_0.jms; + + +public interface MessageProducer extends javax.jms.MessageProducer +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ObjectMessage.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ObjectMessage.java new file mode 100644 index 0000000000..8b59aa284a --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ObjectMessage.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.amqp_1_0.jms; + +public interface ObjectMessage extends Message, javax.jms.ObjectMessage +{ + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Queue.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Queue.java new file mode 100644 index 0000000000..40beac08d1 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Queue.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface Queue extends Destination, javax.jms.Queue +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueBrowser.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueBrowser.java new file mode 100644 index 0000000000..5bb88569a1 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueBrowser.java @@ -0,0 +1,30 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; + +public interface QueueBrowser extends javax.jms.QueueBrowser +{ + Queue getQueue() throws JMSException; + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueConnection.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueConnection.java new file mode 100644 index 0000000000..1375f1c5f2 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueConnection.java @@ -0,0 +1,30 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; + +public interface QueueConnection extends javax.jms.QueueConnection, Connection +{ + QueueSession createQueueSession(boolean b, int i) throws JMSException; + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueReceiver.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueReceiver.java new file mode 100644 index 0000000000..9cc1a36ca7 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueReceiver.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +import javax.jms.JMSException; + +public interface QueueReceiver extends MessageConsumer, javax.jms.QueueReceiver +{ + Queue getQueue() throws JMSException; +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSender.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSender.java new file mode 100644 index 0000000000..824e48364c --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSender.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +import javax.jms.JMSException; + +public interface QueueSender extends MessageProducer, javax.jms.QueueSender +{ + Queue getQueue() throws JMSException; +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSession.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSession.java new file mode 100644 index 0000000000..28d30f60c5 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSession.java @@ -0,0 +1,42 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; + + +public interface QueueSession extends Session, javax.jms.QueueSession +{ + Queue createQueue(String s) throws JMSException; + + QueueReceiver createReceiver(javax.jms.Queue queue) throws JMSException; + + QueueReceiver createReceiver(javax.jms.Queue queue, String s) throws JMSException; + + QueueSender createSender(javax.jms.Queue queue) throws JMSException; + + QueueBrowser createBrowser(javax.jms.Queue queue) throws JMSException; + + QueueBrowser createBrowser(javax.jms.Queue queue, String s) throws JMSException; + + TemporaryQueue createTemporaryQueue() throws JMSException; +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Session.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Session.java new file mode 100644 index 0000000000..0ce9baecea --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Session.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.amqp_1_0.jms; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Queue; +import javax.jms.Topic; + + +import java.io.Serializable; + +public interface Session extends javax.jms.Session +{ + static enum AcknowledgeMode { SESSION_TRANSACTED, AUTO_ACKNOWLEDGE, CLIENT_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE }; + + BytesMessage createBytesMessage() throws JMSException; + + MapMessage createMapMessage() throws JMSException; + + Message createMessage() throws JMSException; + + ObjectMessage createObjectMessage() throws JMSException; + + ObjectMessage createObjectMessage(Serializable serializable) throws JMSException; + + StreamMessage createStreamMessage() throws JMSException; + + TextMessage createTextMessage() throws JMSException; + + TextMessage createTextMessage(String s) throws JMSException; + + AmqpMessage createAmqpMessage() throws JMSException; + + MessageProducer createProducer(Destination destination) throws JMSException; + + MessageConsumer createConsumer(Destination destination) throws JMSException; + + MessageConsumer createConsumer(Destination destination, String s) throws JMSException; + + MessageConsumer createConsumer(Destination destination, String s, boolean b) throws JMSException; + + TopicSubscriber createDurableSubscriber(Topic topic, String s) throws JMSException; + + TopicSubscriber createDurableSubscriber(Topic topic, String s, String s1, boolean b) + throws JMSException; + + QueueBrowser createBrowser(Queue queue) throws JMSException; + + QueueBrowser createBrowser(Queue queue, String s) throws JMSException; + + TemporaryQueue createTemporaryQueue() throws JMSException; + + TemporaryTopic createTemporaryTopic() throws JMSException; + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/StreamMessage.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/StreamMessage.java new file mode 100644 index 0000000000..d207a708c9 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/StreamMessage.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface StreamMessage extends Message, javax.jms.StreamMessage +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryDestination.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryDestination.java new file mode 100644 index 0000000000..025a1af806 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryDestination.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.amqp_1_0.jms; + +public interface TemporaryDestination +{ + Session getSession(); + + boolean isDeleted(); + + void addConsumer(MessageConsumer consumer); + + void removeConsumer(MessageConsumer consumer); +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryQueue.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryQueue.java new file mode 100644 index 0000000000..182f9a4c85 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryQueue.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface TemporaryQueue extends Queue, TemporaryDestination, javax.jms.TemporaryQueue +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryTopic.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryTopic.java new file mode 100644 index 0000000000..277681079b --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryTopic.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface TemporaryTopic extends Topic, TemporaryDestination, javax.jms.TemporaryTopic +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TextMessage.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TextMessage.java new file mode 100644 index 0000000000..1dbcd5f84f --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TextMessage.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface TextMessage extends Message, javax.jms.TextMessage +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Topic.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Topic.java new file mode 100644 index 0000000000..755d698a04 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Topic.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface Topic extends Destination, javax.jms.Topic +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicConnection.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicConnection.java new file mode 100644 index 0000000000..1431c7d2cb --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicConnection.java @@ -0,0 +1,30 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; + +public interface TopicConnection extends Connection, javax.jms.TopicConnection +{ + TopicSession createTopicSession(boolean b, int i) throws JMSException; + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicPublisher.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicPublisher.java new file mode 100644 index 0000000000..dde6c8b606 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicPublisher.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +public interface TopicPublisher extends MessageProducer, javax.jms.TopicPublisher +{ +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSession.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSession.java new file mode 100644 index 0000000000..2c02ff199e --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSession.java @@ -0,0 +1,43 @@ +/* + * + * 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.amqp_1_0.jms; + +import javax.jms.JMSException; + + +public interface TopicSession extends Session,javax.jms.TopicSession +{ + Topic createTopic(String s) throws JMSException; + + TopicSubscriber createSubscriber(javax.jms.Topic topic) throws JMSException; + + TopicSubscriber createSubscriber(javax.jms.Topic topic, String s, boolean b) throws JMSException; + + TopicSubscriber createDurableSubscriber(javax.jms.Topic topic, String s) throws JMSException; + + TopicSubscriber createDurableSubscriber(javax.jms.Topic topic, String s, String s1, boolean b) + throws JMSException; + + TopicPublisher createPublisher(javax.jms.Topic topic) throws JMSException; + + TemporaryTopic createTemporaryTopic() throws JMSException; +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSubscriber.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSubscriber.java new file mode 100644 index 0000000000..00e5e9aca9 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSubscriber.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.jms; + +import javax.jms.JMSException; + +public interface TopicSubscriber extends MessageConsumer, javax.jms.TopicSubscriber +{ + Topic getTopic() throws JMSException; +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java new file mode 100644 index 0000000000..0ca629db7e --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java @@ -0,0 +1,78 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.AmqpMessage; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties; +import org.apache.qpid.amqp_1_0.type.messaging.Footer; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import java.util.*; + +public class AmqpMessageImpl extends MessageImpl implements AmqpMessage +{ + private List
_sections; + + protected AmqpMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, List
sections, + Footer footer, SessionImpl session) + { + super(header, messageAnnotations, properties, appProperties, footer, session); + _sections = sections; + } + + protected AmqpMessageImpl(final SessionImpl session) + { + super(new Header(), new MessageAnnotations(new HashMap()), new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP), + session); + _sections = new ArrayList
(); + } + + public int getSectionCount() + { + return _sections.size(); + } + + public Section getSection(final int position) + { + return _sections.get(position); + } + + public ListIterator
sectionIterator() + { + return _sections.listIterator(); + } + + @Override Collection
getSections() + { + List
sections = new ArrayList
(); + sections.add(getHeader()); + if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty()) + { + sections.add(getMessageAnnotations()); + } + sections.add(getProperties()); + sections.add(getApplicationProperties()); + sections.addAll(_sections); + sections.add(getFooter()); + return sections; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java new file mode 100644 index 0000000000..83cc8eafb5 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java @@ -0,0 +1,538 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.BytesMessage; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import javax.jms.JMSException; +import javax.jms.MessageEOFException; +import javax.jms.MessageFormatException; +import java.io.*; +import java.util.*; + +public class BytesMessageImpl extends MessageImpl implements BytesMessage +{ + private DataInputStream _dataAsInput; + private DataOutputStream _dataAsOutput; + private ByteArrayOutputStream _bytesOut; + private Data _dataIn; + + // message created for reading + protected BytesMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, Data data, + Footer footer, SessionImpl session) + { + super(header, messageAnnotations, properties, appProperties, footer, session); + _dataIn = data; + final Binary dataBuffer = data.getValue(); + _dataAsInput = new DataInputStream(new ByteArrayInputStream(dataBuffer.getArray(),dataBuffer.getArrayOffset(),dataBuffer.getLength())); + + } + + // message created to be sent + protected BytesMessageImpl(final SessionImpl session) + { + super(new Header(), + new MessageAnnotations(new HashMap()), + new Properties(), + new ApplicationProperties(new HashMap()), + new Footer(Collections.EMPTY_MAP), + session); + + _bytesOut = new ByteArrayOutputStream(); + _dataAsOutput = new DataOutputStream(_bytesOut); + } + + + private Data getDataSection() + { + if(_bytesOut != null) + { + return new Data(new Binary(_bytesOut.toByteArray())); + } + else + { + return _dataIn; + } + } + + @Override + protected boolean isReadOnly() + { + return _dataIn != null; + } + + public long getBodyLength() throws JMSException + { + checkReadable(); + return getDataSection().getValue().getLength(); + } + + public boolean readBoolean() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readBoolean(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + + public byte readByte() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readByte(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public int readUnsignedByte() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readUnsignedByte(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public short readShort() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readShort(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public int readUnsignedShort() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readUnsignedShort(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public char readChar() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readChar(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public int readInt() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readInt(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public long readLong() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readLong(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public float readFloat() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readFloat(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public double readDouble() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readDouble(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public String readUTF() throws JMSException + { + checkReadable(); + try + { + return _dataAsInput.readUTF(); + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public int readBytes(byte[] bytes) throws JMSException + { + + return readBytes(bytes, bytes.length); + } + + public int readBytes(byte[] bytes, int length) throws JMSException + { + checkReadable(); + + try + { + int offset = 0; + while(offset < length) + { + int read = _dataAsInput.read(bytes, offset, length - offset); + if(read < 0) + { + break; + } + offset += read; + } + + if(offset == 0 && length != 0) + { + return -1; + } + else + { + return offset; + } + } + catch (IOException e) + { + throw handleInputException(e); + } + } + + public void writeBoolean(boolean b) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeBoolean(b); + } + catch (IOException e) + { + throw handleOutputException(e); + } + + } + + public void writeByte(byte b) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeByte(b); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeShort(short i) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeShort(i); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeChar(char c) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeChar(c); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeInt(int i) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeInt(i); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeLong(long l) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeLong(l); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeFloat(float v) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeFloat(v); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeDouble(double v) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeDouble(v); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeUTF(String s) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.writeUTF(s); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeBytes(byte[] bytes) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.write(bytes); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeBytes(byte[] bytes, int off, int len) throws JMSException + { + checkWritable(); + try + { + _dataAsOutput.write(bytes, off, len); + } + catch (IOException e) + { + throw handleOutputException(e); + } + } + + public void writeObject(Object o) throws JMSException + { + checkWritable(); + if(o == null) + { + throw new NullPointerException("Value passed to BytesMessage.writeObject() must be non null"); + } + else if (o instanceof Boolean) + { + writeBoolean((Boolean)o); + } + else if (o instanceof Byte) + { + writeByte((Byte)o); + } + else if (o instanceof Short) + { + writeShort((Short)o); + } + else if (o instanceof Character) + { + writeChar((Character)o); + } + else if (o instanceof Integer) + { + writeInt((Integer)o); + } + else if(o instanceof Long) + { + writeLong((Long)o); + } + else if(o instanceof Float) + { + writeFloat((Float) o); + } + else if(o instanceof Double) + { + writeDouble((Double) o); + } + else if(o instanceof String) + { + writeUTF((String) o); + } + else if(o instanceof byte[]) + { + writeBytes((byte[])o); + } + else + { + throw new MessageFormatException("Value passed to BytesMessage.writeObject() must be of primitive type. Type passed was " + o.getClass().getName()); + } + } + + public void reset() throws JMSException + { + if(_bytesOut != null) + { + byte[] data = _bytesOut.toByteArray(); + _dataIn = new Data(new Binary(data)); + _dataAsInput = new DataInputStream(new ByteArrayInputStream(data)); + _dataAsOutput = null; + _bytesOut = null; + } + else + { + + final Binary dataBuffer = _dataIn.getValue(); + _dataAsInput = new DataInputStream(new ByteArrayInputStream(dataBuffer.getArray(),dataBuffer.getArrayOffset(),dataBuffer.getLength())); + + } + } + + private JMSException handleInputException(final IOException e) + { + JMSException ex; + if(e instanceof EOFException) + { + ex = new MessageEOFException(e.getMessage()); + } + else + { + ex = new MessageFormatException(e.getMessage()); + } + ex.initCause(e); + ex.setLinkedException(e); + return ex; + } + + private JMSException handleOutputException(final IOException e) + { + JMSException ex = new JMSException(e.getMessage()); + ex.initCause(e); + ex.setLinkedException(e); + return ex; + } + + @Override + public void clearBody() throws JMSException + { + super.clearBody(); + _bytesOut = new ByteArrayOutputStream(); + _dataAsOutput = new DataOutputStream(_bytesOut); + _dataAsInput = null; + _dataIn = null; + } + + @Override Collection
getSections() + { + List
sections = new ArrayList
(); + sections.add(getHeader()); + if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty()) + { + sections.add(getMessageAnnotations()); + } + sections.add(getProperties()); + sections.add(getApplicationProperties()); + sections.add(getDataSection()); + sections.add(getFooter()); + return sections; + } + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java new file mode 100644 index 0000000000..d9e6dfe36d --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java @@ -0,0 +1,173 @@ +/* + * + * 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.amqp_1_0.jms.impl; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.jms.JMSException; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import org.apache.qpid.amqp_1_0.jms.ConnectionFactory; + +public class ConnectionFactoryImpl implements ConnectionFactory, TopicConnectionFactory, QueueConnectionFactory +{ + private String _host; + private int _port; + private String _username; + private String _password; + private String _clientId; + private String _remoteHost; + private boolean _ssl; + + + public ConnectionFactoryImpl(final String host, + final int port, + final String username, + final String password) + { + this(host,port,username,password,null,false); + } + + public ConnectionFactoryImpl(final String host, + final int port, + final String username, + final String password, + final String clientId) + { + this(host,port,username,password,clientId,false); + } + + public ConnectionFactoryImpl(final String host, + final int port, + final String username, + final String password, + final String clientId, + final boolean ssl) + { + this(host,port,username,password,clientId,null,ssl); + } + + public ConnectionFactoryImpl(final String host, + final int port, + final String username, + final String password, + final String clientId, + final String remoteHost, + final boolean ssl) + { + _host = host; + _port = port; + _username = username; + _password = password; + _clientId = clientId; + _remoteHost = remoteHost; + _ssl = ssl; + } + + public ConnectionImpl createConnection() throws JMSException + { + return new ConnectionImpl(_host, _port, _username, _password, _clientId, _remoteHost, _ssl); + } + + public ConnectionImpl createConnection(final String username, final String password) throws JMSException + { + return new ConnectionImpl(_host, _port, username, password, _clientId, _remoteHost, _ssl); + } + + public static ConnectionFactoryImpl createFromURL(final String urlString) throws MalformedURLException + { + URL url = new URL(urlString); + String host = url.getHost(); + int port = url.getPort(); + if(port == -1) + { + port = 5672; + } + String userInfo = url.getUserInfo(); + String username = null; + String password = null; + String clientId = null; + String remoteHost = null; + boolean ssl = false; + if(userInfo != null) + { + String[] components = userInfo.split(":",2); + username = components[0]; + if(components.length == 2) + { + password = components[1]; + } + } + String query = url.getQuery(); + if(query != null) + { + for(String param : query.split("&")) + { + String[] keyValuePair = param.split("=",2); + if(keyValuePair[0].equalsIgnoreCase("clientid")) + { + clientId = keyValuePair[1]; + } + else if(keyValuePair[0].equalsIgnoreCase("ssl")) + { + ssl = Boolean.valueOf(keyValuePair[1]); + } + else if(keyValuePair[0].equalsIgnoreCase("remote-host")) + { + remoteHost = keyValuePair[1]; + } + } + } + + return new ConnectionFactoryImpl(host, port, username, password, clientId, remoteHost, ssl); + + } + + public QueueConnection createQueueConnection() throws JMSException + { + final ConnectionImpl connection = createConnection(); + connection.setQueueConnection(true); + return connection; + } + + public QueueConnection createQueueConnection(final String username, final String password) throws JMSException + { + final ConnectionImpl connection = createConnection(username, password); + connection.setQueueConnection(true); + return connection; + } + + public TopicConnection createTopicConnection() throws JMSException + { + final ConnectionImpl connection = createConnection(); + connection.setTopicConnection(true); + return connection; + } + + public TopicConnection createTopicConnection(final String username, final String password) throws JMSException + { + final ConnectionImpl connection = createConnection(username, password); + connection.setTopicConnection(true); + return connection; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java new file mode 100644 index 0000000000..587b12b51a --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java @@ -0,0 +1,329 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.Connection; +import org.apache.qpid.amqp_1_0.jms.ConnectionMetaData; +import org.apache.qpid.amqp_1_0.jms.Session; +import org.apache.qpid.amqp_1_0.transport.Container; + +import javax.jms.*; +import javax.jms.IllegalStateException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ConnectionImpl implements Connection, QueueConnection, TopicConnection +{ + + private ConnectionMetaData _connectionMetaData; + private volatile ExceptionListener _exceptionListener; + + private final List _sessions = new ArrayList(); + + private final Object _lock = new Object(); + + private org.apache.qpid.amqp_1_0.client.Connection _conn; + private boolean _isQueueConnection; + private boolean _isTopicConnection; + private final Collection _closeTasks = new ArrayList(); + + + private static enum State + { + STOPPED, + STARTED, + CLOSED + } + + private volatile State _state = State.STOPPED; + + public ConnectionImpl(String host, int port, String username, String password, String clientId) throws JMSException + { + this(host,port,username,password,clientId,false); + } + + public ConnectionImpl(String host, int port, String username, String password, String clientId, boolean ssl) throws JMSException + { + this(host,port,username,password,clientId,null,ssl); + } + + public ConnectionImpl(String host, int port, String username, String password, String clientId, String remoteHost, boolean ssl) throws JMSException + { + Container container = clientId == null ? new Container() : new Container(clientId); + // TODO - authentication, containerId, clientId, ssl?, etc + try + { + _conn = new org.apache.qpid.amqp_1_0.client.Connection(host, port, username, password, container, remoteHost, ssl); + // TODO - retrieve negotiated AMQP version + _connectionMetaData = new ConnectionMetaDataImpl(1,0,0); + } + catch (org.apache.qpid.amqp_1_0.client.Connection.ConnectionException e) + { + JMSException jmsEx = new JMSException(e.getMessage()); + jmsEx.setLinkedException(e); + jmsEx.initCause(e); + throw jmsEx; + } + } + + public SessionImpl createSession(final boolean transacted, final int acknowledgeMode) throws JMSException + { + Session.AcknowledgeMode ackMode; + + try + { + ackMode = transacted ? Session.AcknowledgeMode.SESSION_TRANSACTED + : Session.AcknowledgeMode.values()[acknowledgeMode]; + } + catch (IndexOutOfBoundsException e) + { + JMSException jmsEx = new JMSException("Unknown acknowledgement mode " + acknowledgeMode); + jmsEx.setLinkedException(e); + jmsEx.initCause(e); + throw jmsEx; + } + + return createSession(ackMode); + } + + public SessionImpl createSession(final Session.AcknowledgeMode acknowledgeMode) throws JMSException + { + synchronized(_lock) + { + if(_state == State.CLOSED) + { + throw new IllegalStateException("Cannot create a session on a closed connection"); + } + + SessionImpl session = new SessionImpl(this, acknowledgeMode); + session.setQueueSession(_isQueueConnection); + session.setTopicSession(_isTopicConnection); + _sessions.add(session); + + return session; + } + + } + + public String getClientID() throws JMSException + { + checkClosed(); + return _conn.getEndpoint().getContainer().getId(); + } + + public void setClientID(final String s) throws JMSException + { + throw new IllegalStateException("Cannot set client-id to \"" + + s + + "\"; client-id must be set on connection creation"); + } + + public ConnectionMetaData getMetaData() throws JMSException + { + checkClosed(); + return _connectionMetaData; + } + + public ExceptionListener getExceptionListener() throws JMSException + { + checkClosed(); + return _exceptionListener; + } + + public void setExceptionListener(final ExceptionListener exceptionListener) throws JMSException + { + checkClosed(); + _exceptionListener = exceptionListener; + } + + public void start() throws JMSException + { + synchronized(_lock) + { + checkClosed(); + if(_state == State.STOPPED) + { + // TODO + + _state = State.STARTED; + + for(SessionImpl session : _sessions) + { + session.start(); + } + + } + + _lock.notifyAll(); + } + + } + + public void stop() throws JMSException + { + synchronized(_lock) + { + switch(_state) + { + case STARTED: + for(SessionImpl session : _sessions) + { + session.stop(); + } + _state = State.STOPPED; + break; + case CLOSED: + throw new javax.jms.IllegalStateException("Closed"); + } + + _lock.notifyAll(); + } + } + + + static interface CloseTask + { + public void onClose() throws JMSException; + } + + void addOnCloseTask(CloseTask task) + { + synchronized (_lock) + { + _closeTasks.add(task); + } + } + + + void removeOnCloseTask(CloseTask task) + { + synchronized (_lock) + { + _closeTasks.remove(task); + } + } + + public void close() throws JMSException + { + synchronized(_lock) + { + if(_state != State.CLOSED) + { + stop(); + for(SessionImpl session : _sessions) + { + session.close(); + } + for(CloseTask task : _closeTasks) + { + task.onClose(); + } + _conn.close(); + _state = State.CLOSED; + } + + _lock.notifyAll(); + } + } + + private void checkClosed() throws IllegalStateException + { + if(_state == State.CLOSED) + throw new IllegalStateException("Closed"); + } + + public ConnectionConsumer createConnectionConsumer(final Destination destination, + final String s, + final ServerSessionPool serverSessionPool, + final int i) throws JMSException + { + checkClosed(); + return null; //TODO + } + + public TopicSession createTopicSession(final boolean transacted, final int acknowledgeMode) throws JMSException + { + checkClosed(); + SessionImpl session = createSession(transacted, acknowledgeMode); + session.setTopicSession(true); + return session; + } + + public ConnectionConsumer createConnectionConsumer(final Topic topic, + final String s, + final ServerSessionPool serverSessionPool, + final int i) throws JMSException + { + checkClosed(); + return null; //TODO + } + + public ConnectionConsumer createDurableConnectionConsumer(final Topic topic, + final String s, + final String s1, + final ServerSessionPool serverSessionPool, + final int i) throws JMSException + { + checkClosed(); + return null; //TODO + } + + public QueueSession createQueueSession(final boolean transacted, final int acknowledgeMode) throws JMSException + { + checkClosed(); + SessionImpl session = createSession(transacted, acknowledgeMode); + session.setQueueSession(true); + return session; + } + + public ConnectionConsumer createConnectionConsumer(final Queue queue, + final String s, + final ServerSessionPool serverSessionPool, + final int i) throws JMSException + { + checkClosed(); + return null; //TODO + } + + + + protected org.apache.qpid.amqp_1_0.client.Connection getClientConnection() + { + return _conn; + } + + public boolean isStarted() + { + synchronized (_lock) + { + return _state == State.STARTED; + } + } + + void setQueueConnection(final boolean queueConnection) + { + _isQueueConnection = queueConnection; + } + + void setTopicConnection(final boolean topicConnection) + { + _isTopicConnection = topicConnection; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionMetaDataImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionMetaDataImpl.java new file mode 100644 index 0000000000..8159c7116b --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionMetaDataImpl.java @@ -0,0 +1,105 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.ConnectionMetaData; + +import javax.jms.JMSException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; + +public class ConnectionMetaDataImpl implements ConnectionMetaData +{ + private static final int JMS_MAJOR_VERSION = 1; + private static final int JMS_MINOR_VERSION = 1; + + private static final int PROVIDER_MAJOR_VERSION = 1; + private static final int PROVIDER_MINOR_VERSION = 0; + + + private final int _amqpMajorVersion; + private final int _amqpMinorVersion; + private final int _amqpRevisionVersion; + private static final Collection _jmsxProperties = Arrays.asList("JMSXGroupID", "JMSXGroupSeq"); + + public ConnectionMetaDataImpl(final int amqpMajorVersion, final int amqpMinorVersion, final int amqpRevisionVersion) + { + _amqpMajorVersion = amqpMajorVersion; + _amqpMinorVersion = amqpMinorVersion; + _amqpRevisionVersion = amqpRevisionVersion; + } + + public String getJMSVersion() throws JMSException + { + return getJMSMajorVersion() + "." + getJMSMinorVersion(); + } + + public int getJMSMajorVersion() throws JMSException + { + return JMS_MAJOR_VERSION; + } + + public int getJMSMinorVersion() throws JMSException + { + return JMS_MINOR_VERSION; + } + + public String getJMSProviderName() throws JMSException + { + return "AMQP.ORG"; + } + + public String getProviderVersion() throws JMSException + { + return getProviderMajorVersion() + "." + getProviderMinorVersion(); + } + + public int getProviderMajorVersion() throws JMSException + { + return PROVIDER_MAJOR_VERSION; + } + + public int getProviderMinorVersion() throws JMSException + { + return PROVIDER_MINOR_VERSION; + } + + public Enumeration getJMSXPropertyNames() throws JMSException + { + + return Collections.enumeration(_jmsxProperties); + } + + public int getAMQPMajorVersion() + { + return _amqpMajorVersion; + } + + public int getAMQPMinorVersion() + { + return _amqpMinorVersion; + } + + public int getAMQPRevisionVersion() + { + return _amqpRevisionVersion; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DestinationImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DestinationImpl.java new file mode 100644 index 0000000000..b4ca2c6302 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DestinationImpl.java @@ -0,0 +1,85 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.Destination; +import org.apache.qpid.amqp_1_0.jms.Queue; +import org.apache.qpid.amqp_1_0.jms.Topic; + +import javax.jms.JMSException; +import java.util.WeakHashMap; + +public class DestinationImpl implements Destination, Queue, Topic +{ + private static final WeakHashMap DESTINATION_CACHE = + new WeakHashMap(); + + private final String _address; + + protected DestinationImpl(String address) + { + _address = address; + } + + public String getAddress() + { + return _address; + } + + public static DestinationImpl valueOf(String address) + { + return address == null ? null : createDestination(address); + } + + @Override + public int hashCode() + { + return _address.hashCode(); + } + + @Override + public boolean equals(final Object obj) + { + return obj != null + && obj.getClass() == getClass() + && _address.equals(((DestinationImpl)obj)._address); + } + + public static synchronized DestinationImpl createDestination(final String address) + { + DestinationImpl destination = DESTINATION_CACHE.get(address); + if(destination == null) + { + destination = new DestinationImpl(address); + DESTINATION_CACHE.put(address, destination); + } + return destination; + } + + public String getQueueName() throws JMSException + { + return getAddress(); + } + + public String getTopicName() throws JMSException + { + return getAddress(); + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java new file mode 100644 index 0000000000..47811a0f5a --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java @@ -0,0 +1,444 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.MapMessage; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import javax.jms.JMSException; +import javax.jms.MessageFormatException; +import java.util.*; + +public class MapMessageImpl extends MessageImpl implements MapMessage +{ + private Map _map; + + public MapMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, Map map, + Footer footer, + SessionImpl session) + { + super(header, messageAnnotations, properties, appProperties, footer, session); + _map = map; + } + + MapMessageImpl(final SessionImpl session) + { + super(new Header(), new MessageAnnotations(new HashMap()), + new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP), + session); + _map = new HashMap(); + } + + public boolean getBoolean(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Boolean) + { + return ((Boolean) value).booleanValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Boolean.valueOf((String) value); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to boolean."); + } + } + + public byte getByte(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Byte) + { + return ((Byte) value).byteValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Byte.valueOf((String) value).byteValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to byte."); + } } + + public short getShort(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Short) + { + return ((Short) value).shortValue(); + } + else if (value instanceof Byte) + { + return ((Byte) value).shortValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Short.valueOf((String) value).shortValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to short."); + } } + + public char getChar(String name) throws JMSException + { + Object value = get(name); + + if (!itemExists(name)) + { + throw new MessageFormatException("Property " + name + " not present"); + } + else if (value instanceof Character) + { + return ((Character) value).charValue(); + } + else if (value == null) + { + throw new NullPointerException("Property " + name + " has null value and therefore cannot " + + "be converted to char."); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to boolan."); + } } + + public int getInt(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Integer) + { + return ((Integer) value).intValue(); + } + else if (value instanceof Short) + { + return ((Short) value).intValue(); + } + else if (value instanceof Byte) + { + return ((Byte) value).intValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Integer.valueOf((String) value).intValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to int."); + } + } + + public long getLong(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Long) + { + return ((Long) value).longValue(); + } + else if (value instanceof Integer) + { + return ((Integer) value).longValue(); + } + + if (value instanceof Short) + { + return ((Short) value).longValue(); + } + + if (value instanceof Byte) + { + return ((Byte) value).longValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Long.valueOf((String) value).longValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to long."); + } + } + + public float getFloat(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Float) + { + return ((Float) value).floatValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Float.valueOf((String) value).floatValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to float."); + } + } + + public double getDouble(String name) throws JMSException + { + Object value = get(name); + + if (value instanceof Double) + { + return ((Double) value).doubleValue(); + } + else if (value instanceof Float) + { + return ((Float) value).doubleValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Double.valueOf((String) value).doubleValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to double."); + } + } + + public String getString(String name) throws JMSException + { + Object value = get(name); + + if ((value instanceof String) || (value == null)) + { + return (String) value; + } + else if (value instanceof byte[] || value instanceof Binary) + { + throw new MessageFormatException("Property " + name + " of type byte[] " + "cannot be converted to String."); + } + else + { + return value.toString(); + } + } + + public byte[] getBytes(String name) throws JMSException + { + Object value = get(name); + + if (!itemExists(name)) + { + throw new MessageFormatException("Property " + name + " not present"); + } + else if ((value instanceof byte[]) || (value == null)) + { + return (byte[]) value; + } + else if(value instanceof Binary) + { + return ((Binary)value).getArray(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to byte[]."); + } } + + public Object getObject(String s) throws JMSException + { + Object val = get(s); + return val instanceof Binary ? ((Binary)val).getArray() : val; + } + + public Enumeration getMapNames() throws JMSException + { + return Collections.enumeration(keySet()); + } + + public void setBoolean(String name, boolean val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setByte(String name, byte val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setShort(String name, short val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setChar(String name, char val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setInt(String name, int val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setLong(String name, long val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setFloat(String name, float val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setDouble(String name, double val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setString(String name, String val) throws JMSException + { + checkWritable(); + checkPropertyName(name); + put(name, val); + } + + public void setBytes(String name, byte[] val) throws JMSException + { + setBytes(name, val, 0, val == null ? 0 : val.length); + } + + public void setBytes(String name, byte[] bytes, int offset, int length) throws JMSException + { + checkWritable(); + checkPropertyName(name); + byte[] val; + + if(bytes == null) + { + val = null; + } + else + { + val = new byte[length]; + System.arraycopy(bytes,offset,val,0,length); + } + + put(name, new Binary(val)); + } + + public void setObject(String name, Object value) throws JMSException + { + checkWritable(); + checkPropertyName(name); + if ((value instanceof Boolean) || (value instanceof Byte) || (value instanceof Short) || (value instanceof Integer) + || (value instanceof Long) || (value instanceof Character) || (value instanceof Float) + || (value instanceof Double) || (value instanceof String) || (value instanceof byte[]) || (value == null)) + { + put(name, value); + } + else + { + throw new MessageFormatException("Cannot set property " + name + " to value " + value + "of type " + + value.getClass().getName() + "."); + } } + + public boolean itemExists(String s) + { + return _map.containsKey(s); + } + + public Object get(final Object key) + { + return _map.get(key); + } + + public Object put(final Object key, final Object val) + { + return _map.put(key, val); + } + + public boolean itemExists(final Object key) + { + return _map.containsKey(key); + } + + public Set keySet() + { + return _map.keySet(); + } + + @Override + public void clearBody() throws JMSException + { + super.clearBody(); + _map.clear(); + } + + private void checkPropertyName(String propName) + { + if ((propName == null) || propName.equals("")) + { + throw new IllegalArgumentException("Property name cannot be null, or the empty String."); + } + } + + @Override Collection
getSections() + { + List
sections = new ArrayList
(); + sections.add(getHeader()); + if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty()) + { + sections.add(getMessageAnnotations()); + } + sections.add(getProperties()); + sections.add(getApplicationProperties()); + sections.add(new AmqpValue(_map)); + sections.add(getFooter()); + return sections; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java new file mode 100644 index 0000000000..e0402cd0a7 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java @@ -0,0 +1,447 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.AcknowledgeMode; +import org.apache.qpid.amqp_1_0.client.Message; +import org.apache.qpid.amqp_1_0.client.Receiver; +import org.apache.qpid.amqp_1_0.client.Transaction; +import org.apache.qpid.amqp_1_0.jms.MessageConsumer; +import org.apache.qpid.amqp_1_0.jms.QueueReceiver; +import org.apache.qpid.amqp_1_0.jms.Queue; +import org.apache.qpid.amqp_1_0.jms.Session; +import org.apache.qpid.amqp_1_0.jms.TemporaryDestination; +import org.apache.qpid.amqp_1_0.jms.Topic; +import org.apache.qpid.amqp_1_0.jms.TopicSubscriber; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.messaging.Filter; +import org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter; +import org.apache.qpid.amqp_1_0.type.messaging.Modified; +import org.apache.qpid.amqp_1_0.type.messaging.NoLocalFilter; +import org.apache.qpid.amqp_1_0.type.transport.AmqpError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + + +import javax.jms.Destination; +import javax.jms.IllegalStateException; +import javax.jms.InvalidDestinationException; +import javax.jms.InvalidSelectorException; +import javax.jms.JMSException; +import javax.jms.MessageListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MessageConsumerImpl implements MessageConsumer, QueueReceiver, TopicSubscriber +{ + private static final Symbol NO_LOCAL_FILTER_NAME = Symbol.valueOf("no-local"); + private static final Symbol JMS_SELECTOR_FILTER_NAME = Symbol.valueOf("jms-selector"); + private String _selector; + private boolean _noLocal; + private DestinationImpl _destination; + private SessionImpl _session; + private Receiver _receiver; + private Binary _lastUnackedMessage; + MessageListener _messageListener; + + private boolean _isQueueConsumer; + private boolean _isTopicSubscriber; + + private boolean _closed = false; + private String _linkName; + private boolean _durable; + private Collection _txnMsgs = Collections.synchronizedCollection(new ArrayList()); + private Binary _lastTxnUpdate; + private final List _recoverReplayMessages = new ArrayList(); + private final List _replaymessages = new ArrayList(); + + MessageConsumerImpl(final Destination destination, + final SessionImpl session, + final String selector, + final boolean noLocal) throws JMSException + { + this(destination,session,selector,noLocal,null,false); + } + + MessageConsumerImpl(final Destination destination, + final SessionImpl session, + final String selector, + final boolean noLocal, + final String linkName, + final boolean durable) throws JMSException + { + _selector = selector; + _noLocal = noLocal; + _linkName = linkName; + _durable = durable; + if(destination instanceof DestinationImpl) + { + _destination = (DestinationImpl) destination; + if(destination instanceof javax.jms.Queue) + { + _isQueueConsumer = true; + } + else if(destination instanceof javax.jms.Topic) + { + _isTopicSubscriber = true; + } + if(destination instanceof TemporaryDestination) + { + ((TemporaryDestination)destination).addConsumer(this); + } + } + else + { + throw new InvalidDestinationException("Invalid destination class " + destination.getClass().getName()); + } + _session = session; + + _receiver = createClientReceiver(); + + + } + + protected Receiver createClientReceiver() throws JMSException + { + try + { + return _session.getClientSession(). createReceiver(_destination.getAddress(), AcknowledgeMode.ALO, + _linkName, _durable, getFilters(), null); + } + catch (AmqpErrorException e) + { + Error error = e.getError(); + if(AmqpError.INVALID_FIELD.equals(error.getCondition())) + { + throw new InvalidSelectorException(e.getMessage()); + } + else + { + throw new JMSException(e.getMessage(), error.getCondition().getValue().toString()); + + } + } + } + + Map getFilters() + { + if(_selector == null || _selector.trim().equals("")) + { + if(_noLocal) + { + return Collections.singletonMap(NO_LOCAL_FILTER_NAME, (Filter) NoLocalFilter.INSTANCE); + } + else + { + return null; + + } + } + else if(_noLocal) + { + Map filters = new HashMap(); + filters.put(NO_LOCAL_FILTER_NAME, NoLocalFilter.INSTANCE); + filters.put(JMS_SELECTOR_FILTER_NAME, new JMSSelectorFilter(_selector)); + return filters; + } + else + { + return Collections.singletonMap(JMS_SELECTOR_FILTER_NAME, (Filter)new JMSSelectorFilter(_selector)); + } + + + } + + public String getMessageSelector() throws JMSException + { + checkClosed(); + return _selector; + } + + public MessageListener getMessageListener() throws IllegalStateException + { + checkClosed(); + return _messageListener; + } + + public void setMessageListener(final MessageListener messageListener) throws JMSException + { + checkClosed(); + _messageListener = messageListener; + _session.messageListenerSet( this ); + _receiver.setMessageArrivalListener(new Receiver.MessageArrivalListener() + { + + public void messageArrived(final Receiver receiver) + { + _session.messageArrived(MessageConsumerImpl.this); + } + }); + } + + public MessageImpl receive() throws JMSException + { + checkClosed(); + return receiveImpl(-1L); + } + + public MessageImpl receive(final long timeout) throws JMSException + { + checkClosed(); + // TODO - validate timeout > 0 + + return receiveImpl(timeout); + } + + public MessageImpl receiveNoWait() throws JMSException + { + checkClosed(); + return receiveImpl(0L); + } + + private MessageImpl receiveImpl(long timeout) throws IllegalStateException + { + org.apache.qpid.amqp_1_0.client.Message msg; + boolean redelivery; + if(_replaymessages.isEmpty()) + { + msg = receive0(timeout); + redelivery = false; + } + else + { + msg = _replaymessages.remove(0); + redelivery = true; + } + + if(msg != null) + { + preReceiveAction(msg); + } + return createJMSMessage(msg, redelivery); + } + + Message receive0(final long timeout) + { + Message message = _receiver.receive(timeout); + if(_session.getAckModeEnum() == Session.AcknowledgeMode.CLIENT_ACKNOWLEDGE) + { + _recoverReplayMessages.add(message); + } + return message; + } + + + void acknowledge(final org.apache.qpid.amqp_1_0.client.Message msg) + { + _receiver.acknowledge(msg.getDeliveryTag(), _session.getTxn()); + } + + MessageImpl createJMSMessage(final Message msg, boolean redelivery) + { + if(msg != null) + { + MessageFactory factory = _session.getMessageFactory(); + final MessageImpl message = factory.createMessage(_destination, msg); + message.setFromQueue(_isQueueConsumer); + message.setFromTopic(_isTopicSubscriber); + if(redelivery) + { + if(!message.getJMSRedelivered()) + { + message.setJMSRedelivered(true); + } + } + + return message; + } + else + { + return null; + } + } + + public void close() throws JMSException + { + if(!_closed) + { + _closed = true; + + closeUnderlyingReceiver(_receiver); + + if(_destination instanceof TemporaryDestination) + { + ((TemporaryDestination)_destination).removeConsumer(this); + } + } + } + + protected void closeUnderlyingReceiver(Receiver receiver) + { + receiver.close(); + } + + private void checkClosed() throws IllegalStateException + { + if(_closed) + { + throw new javax.jms.IllegalStateException("Closed"); + } + } + + void setLastUnackedMessage(final Binary deliveryTag) + { + _lastUnackedMessage = deliveryTag; + } + + void preReceiveAction(final org.apache.qpid.amqp_1_0.client.Message msg) throws IllegalStateException + { + final int acknowledgeMode = _session.getAcknowledgeMode(); + + if(acknowledgeMode == Session.AUTO_ACKNOWLEDGE + || acknowledgeMode == Session.DUPS_OK_ACKNOWLEDGE + || acknowledgeMode == Session.SESSION_TRANSACTED) + { + acknowledge(msg); + if(acknowledgeMode == Session.SESSION_TRANSACTED) + { + _txnMsgs.add(msg.getDeliveryTag()); + } + } + else if(acknowledgeMode == Session.CLIENT_ACKNOWLEDGE) + { + setLastUnackedMessage(msg.getDeliveryTag()); + } + } + + void acknowledgeAll() + { + if(_lastUnackedMessage != null) + { + Transaction txn = _session.getTxn(); + _receiver.acknowledgeAll(_lastUnackedMessage, txn, null); + if(txn != null) + { + _lastTxnUpdate = _lastUnackedMessage; + } + _lastUnackedMessage = null; + + } + _recoverReplayMessages.clear(); + if(!_replaymessages.isEmpty()) + { + _recoverReplayMessages.addAll(_replaymessages); + } + } + + void postRollback() + { + if(_lastTxnUpdate != null) + { + final Modified outcome = new Modified(); + outcome.setDeliveryFailed(true); + _receiver.updateAll(outcome, _lastTxnUpdate); + _lastTxnUpdate = null; + } + for(Binary tag : _txnMsgs) + { + _receiver.modified(tag); + } + _txnMsgs.clear(); + } + + void postCommit() + { + _lastTxnUpdate = null; + _txnMsgs.clear(); + } + + public DestinationImpl getDestination() throws IllegalStateException + { + checkClosed(); + return _destination; + } + + + public SessionImpl getSession() throws IllegalStateException + { + checkClosed(); + return _session; + } + + public boolean getNoLocal() throws IllegalStateException + { + checkClosed(); + return _noLocal; + } + + public void start() + { + _receiver.setCredit(UnsignedInteger.valueOf(100), true); + } + + public Queue getQueue() throws JMSException + { + return (Queue) getDestination(); + } + + public Topic getTopic() throws JMSException + { + return (Topic) getDestination(); + } + + void setQueueConsumer(final boolean queueConsumer) + { + _isQueueConsumer = queueConsumer; + } + + void setTopicSubscriber(final boolean topicSubscriber) + { + _isTopicSubscriber = topicSubscriber; + } + + String getLinkName() + { + return _linkName; + } + + boolean isDurable() + { + return _durable; + } + + void doRecover() + { + _replaymessages.clear(); + if(!_recoverReplayMessages.isEmpty()) + { + _replaymessages.addAll(_recoverReplayMessages); + for(Message msg : _replaymessages) + { + _session.messageArrived(this); + } + } + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java new file mode 100644 index 0000000000..216107e53e --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java @@ -0,0 +1,191 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.Message; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.*; + +class MessageFactory +{ + private final SessionImpl _session; + + + MessageFactory(final SessionImpl session) + { + _session = session; + } + + public MessageImpl createMessage(final DestinationImpl destination, final Message msg) + { + MessageImpl message; + List
payload = msg.getPayload(); + Header header = null; + MessageAnnotations messageAnnotations = null; + + Properties properties = null; + ApplicationProperties appProperties = null; + Footer footer; + + Iterator
iter = payload.iterator(); + List
body = new ArrayList
(); + + Section section = iter.hasNext() ? iter.next() : null; + + if(section instanceof Header) + { + header = (Header) section; + section = iter.hasNext() ? iter.next() : null; + } + + if(section instanceof MessageAnnotations) + { + messageAnnotations = (MessageAnnotations) section; + section = iter.hasNext() ? iter.next() : null; + } + + if(section instanceof Properties) + { + properties = (Properties) section; + section = iter.hasNext() ? iter.next() : null; + } + + if(section instanceof ApplicationProperties) + { + appProperties = (ApplicationProperties) section; + section = iter.hasNext() ? iter.next() : null; + } + + while(section != null && !(section instanceof Footer)) + { + body.add(section); + section = iter.hasNext() ? iter.next() : null; + } + + footer = (Footer) section; + + if(body.size() == 1) + { + Section bodySection = body.get(0); + if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof Map) + { + message = new MapMessageImpl(header, messageAnnotations, properties, appProperties, (Map) ((AmqpValue)bodySection).getValue(), footer, _session); + } + else if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof List) + { + message = new StreamMessageImpl(header, messageAnnotations, properties, appProperties, + (List) ((AmqpValue)bodySection).getValue(), footer, _session); + } + else if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof String) + { + message = new TextMessageImpl(header, messageAnnotations, properties, appProperties, + (String) ((AmqpValue)bodySection).getValue(), footer, _session); + } + else if(bodySection instanceof AmqpValue && ((AmqpValue)bodySection).getValue() instanceof Binary) + { + + Binary value = (Binary) ((AmqpValue) bodySection).getValue(); + message = new BytesMessageImpl(header, messageAnnotations, properties, appProperties, + new Data(value), footer, _session); + } + else if(bodySection instanceof Data) + { + if(properties != null && ObjectMessageImpl.CONTENT_TYPE.equals(properties.getContentType())) + { + + + message = new ObjectMessageImpl(header, messageAnnotations, properties, appProperties, + (Data) bodySection, + footer, + _session); + } + else + { + message = new BytesMessageImpl(header, messageAnnotations, properties, appProperties, (Data) bodySection, footer, _session); + } + } + else if(bodySection instanceof AmqpSequence) + { + message = new StreamMessageImpl(header, messageAnnotations, properties, appProperties, ((AmqpSequence) bodySection).getValue(), footer, _session); + } + + /*else if(bodySection instanceof AmqpDataSection) + { + AmqpDataSection dataSection = (AmqpDataSection) bodySection; + + List data = new ArrayList(); + + ListIterator dataIter = dataSection.iterator(); + + while(dataIter.hasNext()) + { + data.add(dataIter.next()); + } + + if(data.size() == 1) + { + final Object obj = data.get(0); + if( obj instanceof String) + { + message = new TextMessageImpl(header,properties,appProperties,(String) data.get(0),footer, _session); + } + else if(obj instanceof JavaSerializable) + { + // TODO - ObjectMessage + message = new AmqpMessageImpl(header,properties,appProperties,body,footer, _session); + } + else if(obj instanceof Serializable) + { + message = new ObjectMessageImpl(header,properties,footer,appProperties,(Serializable)obj, _session); + } + else + { + message = new AmqpMessageImpl(header,properties,appProperties,body,footer, _session); + } + } + else + { + // not a text message + message = new AmqpMessageImpl(header,properties,appProperties,body,footer, _session); + } + }*/ + else + { + message = new AmqpMessageImpl(header,messageAnnotations, properties,appProperties,body,footer, _session); + } + } + else + { + message = new AmqpMessageImpl(header,messageAnnotations, properties,appProperties,body,footer, _session); + } + + message.setReadOnly(); + + return message; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java new file mode 100644 index 0000000000..f1056b94fd --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java @@ -0,0 +1,1209 @@ +/* + * + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.Message; +import org.apache.qpid.amqp_1_0.messaging.MessageAttributes; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedByte; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.UnsignedShort; +import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties; +import org.apache.qpid.amqp_1_0.type.messaging.Footer; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.MessageAnnotations; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageFormatException; +import javax.jms.MessageNotReadableException; +import javax.jms.MessageNotWriteableException; +import java.nio.charset.Charset; +import java.util.*; + +public abstract class MessageImpl implements Message +{ + static final Set _supportedClasses = + new HashSet(Arrays.asList(Boolean.class, Byte.class, Short.class, Integer.class, Long.class, + Float.class, Double.class, Character.class, String.class, byte[].class)); + private static final Symbol JMS_TYPE = Symbol.valueOf("x-opt-jms-type"); + + private Header _header; + private Properties _properties; + private ApplicationProperties _applicationProperties; + private Footer _footer; + public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8"); + private SessionImpl _sessionImpl; + private boolean _readOnly; + private MessageAnnotations _messageAnnotations; + + private boolean _isFromQueue; + private boolean _isFromTopic; + private long _expiration; + + protected MessageImpl(Header header, + MessageAnnotations messageAnnotations, + Properties properties, + ApplicationProperties appProperties, + Footer footer, + SessionImpl session) + { + _header = header == null ? new Header() : header; + _properties = properties == null ? new Properties() : properties; + _messageAnnotations = messageAnnotations == null ? new MessageAnnotations(new HashMap()) : messageAnnotations; + _footer = footer == null ? new Footer(Collections.EMPTY_MAP) : footer; + _applicationProperties = appProperties == null ? new ApplicationProperties(new HashMap()) : appProperties; + _sessionImpl = session; + } + + public String getJMSMessageID() throws JMSException + { + Object messageId = getMessageId(); + + return messageId == null ? null : "ID:"+messageId.toString(); + } + + public void setJMSMessageID(String messageId) throws InvalidJMSMEssageIdException + { + if(messageId == null) + { + setMessageId(null); + } + else if(messageId.startsWith("ID:")) + { + setMessageId(messageId.substring(3)); + } + else + { + throw new InvalidJMSMEssageIdException(messageId); + } + } + + public long getJMSTimestamp() throws JMSException + { + Date transmitTime = getTransmitTime(); + return transmitTime == null ? 0 : transmitTime.getTime(); + } + + public void setJMSTimestamp(long l) throws JMSException + { + setTransmitTime(new Date(l)); + if(_expiration != 0l) + { + setTtl(UnsignedInteger.valueOf(_expiration-getTransmitTime().getTime())); + } + } + + public byte[] getJMSCorrelationIDAsBytes() throws JMSException + { + + Object o = getCorrelationId(); + if(o instanceof Binary) + { + Binary correlationIdBinary = (Binary) o; + byte[] correlationId = new byte[correlationIdBinary.getLength()]; + correlationIdBinary.asByteBuffer().get(correlationId); + return correlationId; + } + else + { + return o == null ? null : o.toString().getBytes(); + } + + } + + public void setJMSCorrelationIDAsBytes(byte[] correlationId) throws JMSException + { + if(correlationId == null) + { + setCorrelationId(null); + } + else + { + byte[] dup = new byte[correlationId.length]; + System.arraycopy(correlationId,0,dup,0,correlationId.length); + setCorrelationId(new Binary(dup)); + } + } + + public void setJMSCorrelationID(String s) throws JMSException + { + getProperties().setCorrelationId(s); + } + + public String getJMSCorrelationID() throws JMSException + { + Object o = getProperties().getCorrelationId(); + if(o instanceof Binary) + { + Binary id = (Binary) o; + return new String(id.getArray(), id.getArrayOffset(), id.getLength()); + } + else + { + return o == null ? null : o.toString(); + } + } + + public DestinationImpl getJMSReplyTo() throws JMSException + { + return DestinationImpl.valueOf(getReplyTo()); + } + + public void setJMSReplyTo(Destination destination) throws NonAMQPDestinationException + { + if(destination == null) + { + setReplyTo(null); + } + else if (destination instanceof org.apache.qpid.amqp_1_0.jms.Destination) + { + setReplyTo(((org.apache.qpid.amqp_1_0.jms.Destination)destination).getAddress()); + } + else + { + throw new NonAMQPDestinationException(destination); + } + } + + public DestinationImpl getJMSDestination() throws JMSException + { + return _isFromQueue ? QueueImpl.valueOf(getTo()) + : _isFromTopic ? TopicImpl.valueOf(getTo()) + : DestinationImpl.valueOf(getTo()); + } + + public void setJMSDestination(Destination destination) throws NonAMQPDestinationException + { + if(destination == null) + { + setTo(null); + } + else if (destination instanceof org.apache.qpid.amqp_1_0.jms.Destination) + { + setTo(((org.apache.qpid.amqp_1_0.jms.Destination)destination).getAddress()); + } + else + { + throw new NonAMQPDestinationException(destination); + } + } + + public int getJMSDeliveryMode() throws JMSException + { + if(Boolean.FALSE.equals(getDurable())) + { + return DeliveryMode.NON_PERSISTENT; + } + else + { + return DeliveryMode.PERSISTENT; + } + } + + public void setJMSDeliveryMode(int deliveryMode) throws JMSException + { + switch(deliveryMode) + { + case DeliveryMode.NON_PERSISTENT: + setDurable(false); + break; + case DeliveryMode.PERSISTENT: + setDurable(true); + break; + default: + //TODO + } + } + + public boolean getJMSRedelivered() + { + UnsignedInteger failures = getDeliveryFailures(); + return failures != null && (failures.intValue() != 0); + } + + public void setJMSRedelivered(boolean redelivered) + { + UnsignedInteger failures = getDeliveryFailures(); + if(redelivered) + { + if(failures == null || UnsignedInteger.ZERO.equals(failures)) + { + setDeliveryFailures(UnsignedInteger.ONE); + } + } + else + { + setDeliveryFailures(null); + } + } + + public String getJMSType() throws JMSException + { + Map messageAttrs = _messageAnnotations == null ? null : _messageAnnotations.getValue(); + final Object attrValue = messageAttrs == null ? null : messageAttrs.get(JMS_TYPE); + + return attrValue instanceof String ? attrValue.toString() : null; + } + + public void setJMSType(String s) throws JMSException + { + Map messageAttrs = _messageAnnotations == null ? null : _messageAnnotations.getValue(); + if(messageAttrs == null) + { + messageAttrs = new HashMap(); + _messageAnnotations = new MessageAnnotations(messageAttrs); + } + + messageAttrs.put(JMS_TYPE, s); + } + + public long getJMSExpiration() throws JMSException + { + final UnsignedInteger ttl = getTtl(); + return ttl == null || ttl.longValue() == 0 ? 0 : getJMSTimestamp() + ttl.longValue(); + } + + public void setJMSExpiration(long l) throws JMSException + { + _expiration = l; + if(l == 0) + { + setTtl(UnsignedInteger.ZERO); + } + else + { + if(getTransmitTime() == null) + { + setTransmitTime(new Date()); + } + setTtl(UnsignedInteger.valueOf(l - getTransmitTime().getTime())); + } + } + + public int getJMSPriority() throws JMSException + { + UnsignedByte priority = getPriority(); + return priority == null ? DEFAULT_PRIORITY : priority.intValue(); + } + + public void setJMSPriority(int i) throws InvalidJMSPriorityException + { + if(i >= 0 && i <= 255) + { + setPriority(UnsignedByte.valueOf((byte)i)); + } + else + { + throw new InvalidJMSPriorityException(i); + } + } + + public void clearProperties() throws JMSException + { + _applicationProperties.getValue().clear(); + } + + public boolean propertyExists(final String s) throws JMSException + { + return propertyExists((Object) s); + } + + public boolean getBooleanProperty(final String s) throws JMSException + { + return getBooleanProperty((Object) s); + } + + public byte getByteProperty(final String s) throws JMSException + { + return getByteProperty((Object)s); + } + + public short getShortProperty(final String s) throws JMSException + { + return getShortProperty((Object)s); + } + + public int getIntProperty(final String s) throws JMSException + { + return getIntProperty((Object)s); + } + + public long getLongProperty(final String s) throws JMSException + { + return getLongProperty((Object)s); + } + + public float getFloatProperty(final String s) throws JMSException + { + return getFloatProperty((Object)s); + } + + public double getDoubleProperty(final String s) throws JMSException + { + return getDoubleProperty((Object)s); + } + + public String getStringProperty(final String s) throws JMSException + { + return getStringProperty((Object)s); + } + + public Object getObjectProperty(final String s) throws JMSException + { + return getObjectProperty((Object)s); + } + + public boolean propertyExists(Object name) throws JMSException + { + return _applicationProperties.getValue().containsKey(name); + } + + public boolean getBooleanProperty(Object name) throws JMSException + { + + Object value = getProperty(name); + + if (value instanceof Boolean) + { + return ((Boolean) value).booleanValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Boolean.valueOf((String) value); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to boolean."); + } + } + + public byte getByteProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof Byte) + { + return ((Byte) value).byteValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Byte.valueOf((String) value).byteValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to byte."); + } + } + + public short getShortProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof Short) + { + return ((Short) value).shortValue(); + } + else if (value instanceof Byte) + { + return ((Byte) value).shortValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Short.valueOf((String) value).shortValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to short."); + } + } + + private Object getProperty(final Object name) + { + return _applicationProperties.getValue().get(name); + } + + public int getIntProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof Integer) + { + return ((Integer) value).intValue(); + } + else if (value instanceof Short) + { + return ((Short) value).intValue(); + } + else if (value instanceof Byte) + { + return ((Byte) value).intValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Integer.valueOf((String) value).intValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to int."); + } + } + + public long getLongProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof Long) + { + return ((Long) value).longValue(); + } + else if (value instanceof Integer) + { + return ((Integer) value).longValue(); + } + + if (value instanceof Short) + { + return ((Short) value).longValue(); + } + + if (value instanceof Byte) + { + return ((Byte) value).longValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Long.valueOf((String) value).longValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to long."); + } + } + + public float getFloatProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof Float) + { + return ((Float) value).floatValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Float.valueOf((String) value).floatValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to float."); + } + } + + public double getDoubleProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof Double) + { + return ((Double) value).doubleValue(); + } + else if (value instanceof Float) + { + return ((Float) value).doubleValue(); + } + else if ((value instanceof String) || (value == null)) + { + return Double.valueOf((String) value).doubleValue(); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to double."); + } + } + + public String getStringProperty(Object name) throws JMSException + { + Object value = getProperty(name); + + if ((value instanceof String) || (value == null)) + { + return (String) value; + } + else if (value instanceof byte[]) + { + throw new MessageFormatException("Property " + name + " of type byte[] " + "cannot be converted to String."); + } + else + { + return value.toString(); + } + } + + public Object getObjectProperty(Object name) throws JMSException + { + return getProperty(name); + } + + public List getListProperty(final Object name) throws JMSException + { + Object value = getProperty(name); + if(value instanceof List || value == null) + { + return (List)value; + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to List."); + } + } + + public Map getMapProperty(final Object name) throws JMSException + { + Object value = getProperty(name); + if(value instanceof Map || value == null) + { + return (Map)value; + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to Map."); + } + } + + public UnsignedByte getUnsignedByteProperty(final Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof UnsignedByte) + { + return (UnsignedByte) value; + } + else if ((value instanceof String) || (value == null)) + { + return UnsignedByte.valueOf((String) value); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to UnsignedByte."); + } + } + + public UnsignedShort getUnsignedShortProperty(final Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof UnsignedShort) + { + return (UnsignedShort) value; + } + else if (value instanceof UnsignedByte) + { + return UnsignedShort.valueOf(((UnsignedByte)value).shortValue()); + } + else if ((value instanceof String) || (value == null)) + { + return UnsignedShort.valueOf((String) value); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to UnsignedShort."); + } + } + + public UnsignedInteger getUnsignedIntProperty(final Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof UnsignedInteger) + { + return (UnsignedInteger) value; + } + else if (value instanceof UnsignedByte) + { + return UnsignedInteger.valueOf(((UnsignedByte)value).intValue()); + } + else if (value instanceof UnsignedShort) + { + return UnsignedInteger.valueOf(((UnsignedShort)value).intValue()); + } + else if ((value instanceof String) || (value == null)) + { + return UnsignedInteger.valueOf((String) value); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to UnsignedShort."); + } + } + + public UnsignedLong getUnsignedLongProperty(final Object name) throws JMSException + { + Object value = getProperty(name); + + if (value instanceof UnsignedLong) + { + return (UnsignedLong) value; + } + else if (value instanceof UnsignedByte) + { + return UnsignedLong.valueOf(((UnsignedByte)value).longValue()); + } + else if (value instanceof UnsignedShort) + { + return UnsignedLong.valueOf(((UnsignedShort)value).longValue()); + } + else if (value instanceof UnsignedInteger) + { + return UnsignedLong.valueOf(((UnsignedInteger)value).longValue()); + } + else if ((value instanceof String) || (value == null)) + { + return UnsignedLong.valueOf((String) value); + } + else + { + throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName() + + " cannot be converted to UnsignedShort."); + } + } + + public Enumeration getPropertyNames() throws JMSException + { + final Collection names = new ArrayList(); + for(Object key : _applicationProperties.getValue().keySet()) + { + if(key instanceof String) + { + names.add((String)key); + } + } + return Collections.enumeration(names); + } + + public void setBooleanProperty(final String s, final boolean b) throws JMSException + { + checkWritable(); + checkPropertyName(s); + setBooleanProperty((Object)s, b); + } + + protected void checkPropertyName(CharSequence propertyName) + { + if (propertyName == null) + { + throw new IllegalArgumentException("Property name must not be null"); + } + else if (propertyName.length() == 0) + { + throw new IllegalArgumentException("Property name must not be the empty string"); + } + + checkIdentiferFormat(propertyName); + } + + protected void checkIdentiferFormat(CharSequence propertyName) + { +// JMS requirements 3.5.1 Property Names +// Identifiers: +// - An identifier is an unlimited-length character sequence that must begin +// with a Java identifier start character; all following characters must be Java +// identifier part characters. An identifier start character is any character for +// which the method Character.isJavaIdentifierStart returns true. This includes +// '_' and '$'. An identifier part character is any character for which the +// method Character.isJavaIdentifierPart returns true. +// - Identifiers cannot be the names NULL, TRUE, or FALSE. +// Identifiers cannot be NOT, AND, OR, BETWEEN, LIKE, IN, IS, or +// ESCAPE. +// Identifiers are either header field references or property references. The +// type of a property value in a message selector corresponds to the type +// used to set the property. If a property that does not exist in a message is +// referenced, its value is NULL. The semantics of evaluating NULL values +// in a selector are described in Section 3.8.1.2, Null Values. +// The conversions that apply to the get methods for properties do not +// apply when a property is used in a message selector expression. For +// example, suppose you set a property as a string value, as in the +// following: +// myMessage.setStringProperty("NumberOfOrders", "2") +// The following expression in a message selector would evaluate to false, +// because a string cannot be used in an arithmetic expression: +// "NumberOfOrders > 1" +// Identifiers are case sensitive. +// Message header field references are restricted to JMSDeliveryMode, +// JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and +// JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be +// null and if so are treated as a NULL value. + + // JMS start character + if (!(Character.isJavaIdentifierStart(propertyName.charAt(0)))) + { + throw new IllegalArgumentException("Identifier '" + propertyName + "' does not start with a valid JMS identifier start character"); + } + + // JMS part character + int length = propertyName.length(); + for (int c = 1; c < length; c++) + { + if (!(Character.isJavaIdentifierPart(propertyName.charAt(c)))) + { + throw new IllegalArgumentException("Identifier '" + propertyName + "' contains an invalid JMS identifier character"); + } + } + + // JMS invalid names + if ((propertyName.equals("NULL") + || propertyName.equals("TRUE") + || propertyName.equals("FALSE") + || propertyName.equals("NOT") + || propertyName.equals("AND") + || propertyName.equals("OR") + || propertyName.equals("BETWEEN") + || propertyName.equals("LIKE") + || propertyName.equals("IN") + || propertyName.equals("IS") + || propertyName.equals("ESCAPE"))) + { + throw new IllegalArgumentException("Identifier '" + propertyName + "' is not allowed in JMS"); + } + + } + + public void setByteProperty(final String s, final byte b) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setByteProperty((Object)s, b); + } + + public void setShortProperty(final String s, final short i) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setShortProperty((Object)s, i); + } + + public void setIntProperty(final String s, final int i) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setIntProperty((Object)s, i); + } + + public void setLongProperty(final String s, final long l) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setLongProperty((Object)s, l); + } + + public void setFloatProperty(final String s, final float v) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setFloatProperty((Object) s, v); + } + + public void setDoubleProperty(final String s, final double v) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setDoubleProperty((Object)s, v); + } + + public void setStringProperty(final String s, final String s1) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + setStringProperty((Object)s, s1); + } + + public void setObjectProperty(final String s, final Object o) throws JMSException + { + checkWritable(); + checkPropertyName(s); + + if(o != null && (_supportedClasses.contains(o.getClass()))) + { + setObjectProperty((Object)s, o); + } + else + { + throw new MessageFormatException("Cannot call setObjectProperty with a value of " + ((o == null) ? "null" : " class "+o.getClass().getName()) + "."); + } + } + + public void setBooleanProperty(Object name, boolean b) throws JMSException + { + _applicationProperties.getValue().put(name, b); + } + + public void setByteProperty(Object name, byte b) throws JMSException + { + _applicationProperties.getValue().put(name, b); + } + + public void setShortProperty(Object name, short i) throws JMSException + { + _applicationProperties.getValue().put(name, i); + } + + public void setIntProperty(Object name, int i) throws JMSException + { + _applicationProperties.getValue().put(name, i); + } + + public void setLongProperty(Object name, long l) throws JMSException + { + _applicationProperties.getValue().put(name, l); + } + + public void setFloatProperty(Object name, float v) throws JMSException + { + _applicationProperties.getValue().put(name, v); + } + + public void setDoubleProperty(Object name, double v) throws JMSException + { + _applicationProperties.getValue().put(name, v); + } + + public void setStringProperty(Object name, String value) throws JMSException + { + _applicationProperties.getValue().put(name, value); + } + + public void setObjectProperty(Object name, Object value) throws JMSException + { + _applicationProperties.getValue().put(name, value); + } + + public void setListProperty(final Object name, final List list) throws JMSException + { + _applicationProperties.getValue().put(name, list); + } + + public void setMapProperty(final Object name, final Map map) throws JMSException + { + _applicationProperties.getValue().put(name, map); + } + + public void setUnsignedByteProperty(final Object name, final UnsignedByte b) throws JMSException + { + _applicationProperties.getValue().put(name, b); + } + + public void setUnsignedShortProperty(final Object name, final UnsignedShort s) throws JMSException + { + _applicationProperties.getValue().put(name, s); + } + + public void setUnsignedIntProperty(final Object name, final UnsignedInteger i) throws JMSException + { + _applicationProperties.getValue().put(name, i); + } + + public void setUnsignedLongProperty(final Object name, final UnsignedLong l) throws JMSException + { + _applicationProperties.getValue().put(name, l); + } + + public UnsignedInteger getDeliveryFailures() + { + return _header.getDeliveryCount(); + } + + public void setDeliveryFailures(UnsignedInteger failures) + { + _header.setDeliveryCount(failures); + } + + public MessageAttributes getHeaderMessageAttrs() + { + // TODO + return null ; // _header.getMessageAttrs(); + } + + public void setHeaderMessageAttrs(final MessageAttributes messageAttrs) + { + // TODO + } + + public MessageAttributes getHeaderDeliveryAttrs() + { + // TODO + return null ; //_header.getDeliveryAttrs(); + } + + public void setHeaderDeliveryAttrs(final MessageAttributes deliveryAttrs) + { + //TODO + } + + public Boolean getDurable() + { + return _header.getDurable(); + } + + public void setDurable(final Boolean durable) + { + _header.setDurable(durable); + } + + public UnsignedByte getPriority() + { + return _header.getPriority(); + } + + public void setPriority(final UnsignedByte priority) + { + _header.setPriority(priority); + } + + public Date getTransmitTime() + { + return _properties.getCreationTime(); + } + + public void setTransmitTime(final Date transmitTime) + { + _properties.setCreationTime(transmitTime); + } + + public UnsignedInteger getTtl() + { + return _header.getTtl(); + } + + public void setTtl(final UnsignedInteger ttl) + { + _header.setTtl(ttl); + } + + public UnsignedInteger getFormerAcquirers() + { + return _header.getDeliveryCount(); + } + + public void setFormerAcquirers(final UnsignedInteger formerAcquirers) + { + _header.setDeliveryCount(formerAcquirers); + } + + public Object getMessageId() + { + return _properties.getMessageId(); + } + + public void setMessageId(final Object messageId) + { + _properties.setMessageId(messageId); + } + + public Binary getUserId() + { + return _properties.getUserId(); + } + + public void setUserId(final Binary userId) + { + _properties.setUserId(userId); + } + + public String getTo() + { + return _properties.getTo(); + } + + public void setTo(final String to) + { + _properties.setTo(to); + } + + public String getSubject() + { + return _properties.getSubject(); + } + + public void setSubject(final String subject) + { + _properties.setSubject(subject); + } + + public String getReplyTo() + { + return _properties.getReplyTo(); + } + + public void setReplyTo(final String replyTo) + { + _properties.setReplyTo(replyTo); + } + + public Object getCorrelationId() + { + return _properties.getCorrelationId(); + } + + public void setCorrelationId(final Binary correlationId) + { + _properties.setCorrelationId(correlationId); + } + + public Symbol getContentType() + { + return _properties.getContentType(); + } + + public void setContentType(final Symbol contentType) + { + _properties.setContentType(contentType); + } + + public void acknowledge() throws JMSException + { + _sessionImpl.acknowledgeAll(); + } + + public void clearBody() throws JMSException + { + _readOnly = false; + } + + protected boolean isReadOnly() + { + return _readOnly; + } + + protected void checkReadable() throws MessageNotReadableException + { + if (!isReadOnly()) + { + throw new MessageNotReadableException("You need to call reset() to make the message readable"); + } + } + + protected void checkWritable() throws MessageNotWriteableException + { + if (isReadOnly()) + { + throw new MessageNotWriteableException("You need to call clearBody() to make the message writable"); + } + } + + public void setReadOnly() + { + _readOnly = true; + } + + private static class InvalidJMSMEssageIdException extends JMSException + { + public InvalidJMSMEssageIdException(String messageId) + { + super("Invalid JMSMessageID: '" + messageId + "', JMSMessageID MUST start with 'ID:'"); + } + } + + private class NonAMQPDestinationException extends JMSException + { + public NonAMQPDestinationException(Destination destination) + { + super("Destinations not a valid AMQP Destination, class of type: '" + + destination.getClass().getName() + + "', require '" + + org.apache.qpid.amqp_1_0.jms.Destination.class.getName() + "'."); + } + } + + private class InvalidJMSPriorityException extends JMSException + { + public InvalidJMSPriorityException(int priority) + { + super("The provided priority: " + priority + " is not valid in AMQP, valid values are from 0 to 255"); + } + } + + Header getHeader() + { + return _header; + } + + Properties getProperties() + { + return _properties; + } + + + Footer getFooter() + { + return _footer; + } + + MessageAnnotations getMessageAnnotations() + { + return _messageAnnotations; + } + + public ApplicationProperties getApplicationProperties() + { + return _applicationProperties; + } + + public void reset() throws JMSException + { + _readOnly = true; + } + + void setFromQueue(final boolean fromQueue) + { + _isFromQueue = fromQueue; + } + + void setFromTopic(final boolean fromTopic) + { + _isFromTopic = fromTopic; + } + + abstract Collection
getSections(); +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java new file mode 100644 index 0000000000..5bb8845eb7 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java @@ -0,0 +1,362 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.Sender; +import org.apache.qpid.amqp_1_0.jms.MessageProducer; +import org.apache.qpid.amqp_1_0.jms.Queue; +import org.apache.qpid.amqp_1_0.jms.QueueSender; +import org.apache.qpid.amqp_1_0.jms.TemporaryDestination; +import org.apache.qpid.amqp_1_0.jms.TopicPublisher; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; + +import javax.jms.*; +import javax.jms.IllegalStateException; +import java.util.UUID; + +public class MessageProducerImpl implements MessageProducer, QueueSender, TopicPublisher +{ + private boolean _disableMessageID; + private boolean _disableMessageTimestamp; + private int _deliveryMode = Message.DEFAULT_DELIVERY_MODE; + private int _priority = Message.DEFAULT_PRIORITY; + private long _timeToLive; + + private DestinationImpl _destination; + private SessionImpl _session; + private Sender _sender; + private boolean _closed; + + protected MessageProducerImpl(final Destination destination, + final SessionImpl session) throws JMSException + { + if(destination instanceof DestinationImpl) + { + _destination = (DestinationImpl) destination; + } + else if(destination != null) + { + throw new InvalidDestinationException("Invalid Destination Class" + destination.getClass().getName()); + } + _session = session; + + if(_destination != null) + { + try + { + _sender = _session.getClientSession().createSender(_destination.getAddress()); + } + catch (Sender.SenderCreationException e) + { + // TODO - refine exception + JMSException jmsEx = new JMSException(e.getMessage()); + jmsEx.initCause(e); + jmsEx.setLinkedException(e); + throw jmsEx; + } + } + } + + private void checkClosed() throws IllegalStateException + { + if(_closed) + { + throw new javax.jms.IllegalStateException("Producer closed"); + } + } + + public boolean getDisableMessageID() throws IllegalStateException + { + checkClosed(); + return _disableMessageID; + } + + public void setDisableMessageID(final boolean disableMessageID) throws IllegalStateException + { + checkClosed(); + _disableMessageID = disableMessageID; + } + + public boolean getDisableMessageTimestamp() throws IllegalStateException + { + checkClosed(); + return _disableMessageTimestamp; + } + + public void setDisableMessageTimestamp(final boolean disableMessageTimestamp) throws IllegalStateException + { + checkClosed(); + _disableMessageTimestamp = disableMessageTimestamp; + } + + public int getDeliveryMode() throws IllegalStateException + { + checkClosed(); + return _deliveryMode; + } + + public void setDeliveryMode(final int deliveryMode) throws IllegalStateException + { + checkClosed(); + _deliveryMode = deliveryMode; + } + + public int getPriority() throws IllegalStateException + { + checkClosed(); + return _priority; + } + + public void setPriority(final int priority) throws IllegalStateException + { + checkClosed(); + _priority = priority; + } + + public long getTimeToLive() throws IllegalStateException + { + checkClosed(); + return _timeToLive; + } + + public void setTimeToLive(final long timeToLive) throws IllegalStateException + { + checkClosed(); + _timeToLive = timeToLive; + } + + public DestinationImpl getDestination() throws JMSException + { + checkClosed(); + return _destination; + } + + public void close() throws JMSException + { + try + { + if(!_closed) + { + _closed = true; + if(_sender != null) + { + _sender.close(); + } + } + + } + catch (Sender.SenderClosingException e) + { + final JMSException jmsException = new JMSException("error closing"); + jmsException.setLinkedException(e); + throw jmsException; + } + } + + public void send(final Message message) throws JMSException + { + send(message, getDeliveryMode(), getPriority(), getTimeToLive()); + } + + public void send(final Message message, final int deliveryMode, final int priority, final long ttl) throws JMSException + { + if(_sender == null) + { + throw new UnsupportedOperationException("No Destination provided"); + } + if(_destination instanceof TemporaryDestination && ((TemporaryDestination)_destination).isDeleted()) + { + throw new IllegalStateException("Destination is deleted"); + } + + + //TODO + MessageImpl msg; + if(message instanceof org.apache.qpid.amqp_1_0.jms.Message) + { + msg = (MessageImpl) message; + } + else + { + msg = _session.convertMessage(message); + } + + + + msg.setJMSDeliveryMode(deliveryMode); + msg.setJMSPriority(priority); + + msg.setJMSDestination(_destination); + + long timestamp = 0l; + + if(!getDisableMessageTimestamp() || ttl != 0) + { + timestamp = System.currentTimeMillis(); + msg.setJMSTimestamp(timestamp); + + } + if(ttl != 0) + { + msg.setTtl(UnsignedInteger.valueOf(ttl)); + } + else + { + msg.setTtl(null); + } + + if(!getDisableMessageID() && msg.getMessageId() == null) + { + final Binary messageId = generateMessageId(); + msg.setMessageId(messageId); + + } + + if(message != msg) + { + message.setJMSTimestamp(msg.getJMSTimestamp()); + message.setJMSMessageID(msg.getJMSMessageID()); + message.setJMSDeliveryMode(msg.getJMSDeliveryMode()); + message.setJMSPriority(msg.getJMSPriority()); + message.setJMSExpiration(msg.getJMSExpiration()); + } + + + final org.apache.qpid.amqp_1_0.client.Message clientMessage = new org.apache.qpid.amqp_1_0.client.Message(msg.getSections()); + + _sender.send(clientMessage, _session.getTxn()); + + if(getDestination() != null) + { + message.setJMSDestination(getDestination()); + } + } + + public void send(final javax.jms.Queue queue, final Message message) throws JMSException + { + send((Destination)queue, message); + } + + public void send(final javax.jms.Queue queue, final Message message, final int deliveryMode, final int priority, final long ttl) + throws JMSException + { + send((Destination)queue, message, deliveryMode, priority, ttl); + } + + private Binary generateMessageId() + { + UUID uuid = UUID.randomUUID(); + return new Binary(uuid.toString().getBytes()); + } + + public void send(final Destination destination, final Message message) throws JMSException + { + send(destination, message, getDeliveryMode(), getPriority(), getTimeToLive()); + } + + public void send(final Destination destination, final Message message, final int deliveryMode, final int priority, final long ttl) + throws JMSException + { + + checkClosed(); + if(destination == null) + { + send(message, deliveryMode, priority, ttl); + } + else + { + if(_destination != null) + { + throw new UnsupportedOperationException("Cannot use explicit destination pon non-anonymous producer"); + } + else if(!(destination instanceof DestinationImpl)) + { + throw new InvalidDestinationException("Invalid Destination Class" + destination.getClass().getName()); + } + else if(destination instanceof TemporaryDestination && ((TemporaryDestination)destination).isDeleted()) + { + throw new IllegalStateException("Destination has been deleted"); + } + try + { + _destination = (DestinationImpl) destination; + _sender = _session.getClientSession().createSender(_destination.getAddress()); + + send(message, deliveryMode, priority, ttl); + + _sender.close(); + + + + } + catch (Sender.SenderCreationException e) + { + // TODO - refine exception + JMSException jmsEx = new JMSException(e.getMessage()); + jmsEx.initCause(e); + jmsEx.setLinkedException(e); + throw jmsEx; + } + catch (Sender.SenderClosingException e) + { + JMSException jmsEx = new JMSException(e.getMessage()); + jmsEx.initCause(e); + jmsEx.setLinkedException(e); + throw jmsEx; + } + finally + { + _sender = null; + _destination = null; + } + } + } + + public QueueImpl getQueue() throws JMSException + { + return (QueueImpl) getDestination(); + } + + public TopicImpl getTopic() throws JMSException + { + return (TopicImpl) getDestination(); + } + + public void publish(final Message message) throws JMSException + { + send(message); + } + + public void publish(final Message message, final int deliveryMode, final int priority, final long ttl) throws JMSException + { + send(message, deliveryMode, priority, ttl); + } + + public void publish(final Topic topic, final Message message) throws JMSException + { + send(topic, message); + } + + public void publish(final Topic topic, final Message message, final int deliveryMode, final int priority, final long ttl) + throws JMSException + { + send(topic, message, deliveryMode, priority, ttl); + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java new file mode 100644 index 0000000000..2a52b0557a --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java @@ -0,0 +1,143 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.ObjectMessage; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import javax.jms.JMSException; +import javax.jms.MessageNotWriteableException; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.*; + +public class ObjectMessageImpl extends MessageImpl implements ObjectMessage +{ + static final Symbol CONTENT_TYPE = Symbol.valueOf("application/x-java-serialized-object"); + + private Data _objectData; + + protected ObjectMessageImpl(Header header, + MessageAnnotations messageAnnotations, + Properties properties, + ApplicationProperties appProperties, + Data dataSection, + Footer footer, + SessionImpl session) + { + super(header, messageAnnotations, properties, appProperties, footer, session); + getProperties().setContentType(CONTENT_TYPE); + Serializable serializable = null; + _objectData = dataSection; + + } + + protected ObjectMessageImpl(final SessionImpl session) + { + super(new Header(), new MessageAnnotations(new HashMap()), + new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP), + session); + getProperties().setContentType(CONTENT_TYPE); + } + + public void setObject(final Serializable serializable) throws MessageNotWriteableException + { + checkWritable(); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(serializable); + oos.flush(); + oos.close(); + + _objectData = new Data(new Binary(baos.toByteArray())); + + } + catch (IOException e) + { + e.printStackTrace(); //TODO + } + } + + public Serializable getObject() throws JMSException + { + + if(_objectData == null) + { + return null; + } + + Binary data = _objectData.getValue(); + + try + { + ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data.getArray(), data.getArrayOffset(), data.getLength())); + return (Serializable) ois.readObject(); + } + catch (IOException e) + { + JMSException jmsException = new JMSException(e.getMessage()); + jmsException.setLinkedException(e); + throw jmsException; + } + catch (ClassNotFoundException e) + { + + JMSException jmsException = new JMSException(e.getMessage()); + jmsException.setLinkedException(e); + throw jmsException; + } + + } + + @Override + public void clearBody() throws JMSException + { + super.clearBody(); + _objectData = null; + } + + @Override Collection
getSections() + { + List
sections = new ArrayList
(); + sections.add(getHeader()); + if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty()) + { + sections.add(getMessageAnnotations()); + } + sections.add(getProperties()); + sections.add(getApplicationProperties()); + + sections.add(_objectData); + + sections.add(getFooter()); + return sections; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java new file mode 100644 index 0000000000..527e82eaed --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java @@ -0,0 +1,138 @@ +/* + * 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.amqp_1_0.jms.impl; + +import java.util.Collections; +import java.util.Enumeration; +import java.util.Map; +import javax.jms.InvalidSelectorException; +import javax.jms.JMSException; +import org.apache.qpid.amqp_1_0.client.AcknowledgeMode; +import org.apache.qpid.amqp_1_0.client.Message; +import org.apache.qpid.amqp_1_0.client.Receiver; +import org.apache.qpid.amqp_1_0.jms.QueueBrowser; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.Filter; +import org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter; +import org.apache.qpid.amqp_1_0.type.messaging.StdDistMode; +import org.apache.qpid.amqp_1_0.type.transport.AmqpError; + +public class QueueBrowserImpl implements QueueBrowser +{ + private static final String JMS_SELECTOR = "jms-selector"; + private QueueImpl _queue; + private String _selector; + private Receiver _receiver; + private Message _nextElement; + private MessageEnumeration _enumeration; + + QueueBrowserImpl(final QueueImpl queue, final String selector, SessionImpl session) throws JMSException + { + _queue = queue; + _selector = selector; + + + Map filters; + if(selector == null || selector.trim().equals("")) + { + filters = null; + } + else + { + filters = Collections.singletonMap(Symbol.valueOf(JMS_SELECTOR),(Filter) new JMSSelectorFilter(_selector)); + } + + + try + { + _receiver = session.getClientSession().createReceiver(queue.getAddress(), + StdDistMode.COPY, + AcknowledgeMode.AMO,null, + false, + filters, null); + _nextElement = _receiver.receive(0L); + _enumeration = new MessageEnumeration(); + } + catch(AmqpErrorException e) + { + org.apache.qpid.amqp_1_0.type.transport.Error error = e.getError(); + if(AmqpError.INVALID_FIELD.equals(error.getCondition())) + { + throw new InvalidSelectorException(e.getMessage()); + } + else + { + throw new JMSException(e.getMessage(), error.getCondition().getValue().toString()); + } + + } + } + + public QueueImpl getQueue() + { + return _queue; + } + + public String getMessageSelector() + { + return _selector; + } + + public Enumeration getEnumeration() throws JMSException + { + if(_enumeration == null) + { + throw new IllegalStateException("Browser has been closed"); + } + return _enumeration; + } + + public void close() throws JMSException + { + _receiver.close(); + _enumeration = null; + } + + private final class MessageEnumeration implements Enumeration + { + + @Override + public boolean hasMoreElements() + { + return _nextElement != null; + } + + @Override + public Message nextElement() + { + + Message message = _nextElement; + if(message == null) + { + message = _receiver.receive(0l); + } + if(message != null) + { + _nextElement = _receiver.receive(0l); + } + return message; + } + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueConnectionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueConnectionImpl.java new file mode 100644 index 0000000000..657efd80a3 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueConnectionImpl.java @@ -0,0 +1,48 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.QueueConnection; + +import javax.jms.ConnectionConsumer; +import javax.jms.JMSException; +import javax.jms.Queue; +import javax.jms.ServerSessionPool; + +public class QueueConnectionImpl extends ConnectionImpl implements QueueConnection +{ + QueueConnectionImpl(String host, int port, String username, String password, String clientId) + throws JMSException + { + super(host, port, username, password, clientId); + } + + public QueueSessionImpl createQueueSession(final boolean b, final int i) throws JMSException + { + return null; //TODO + } + + public ConnectionConsumer createConnectionConsumer(final Queue queue, + final String s, + final ServerSessionPool serverSessionPool, + final int i) throws JMSException + { + return null; //TODO + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueImpl.java new file mode 100644 index 0000000000..c88bd8268c --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueImpl.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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.Queue; + +import java.util.WeakHashMap; + +public class QueueImpl extends DestinationImpl implements Queue +{ + private static final WeakHashMap QUEUE_CACHE = + new WeakHashMap(); + + public QueueImpl(String address) + { + super(address); + } + + public String getQueueName() + { + return getAddress(); + } + + public static synchronized QueueImpl createQueue(final String address) + { + QueueImpl queue = QUEUE_CACHE.get(address); + if(queue == null) + { + queue = new QueueImpl(address); + QUEUE_CACHE.put(address, queue); + } + return queue; + } + + public static QueueImpl valueOf(String address) + { + return address == null ? null : createQueue(address); + } + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java new file mode 100644 index 0000000000..d46ed7183f --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.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. + */ +package org.apache.qpid.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.Receiver; +import org.apache.qpid.amqp_1_0.jms.Queue; +import org.apache.qpid.amqp_1_0.jms.QueueReceiver; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +import javax.jms.*; + +public class QueueReceiverImpl extends MessageConsumerImpl implements QueueReceiver +{ + QueueReceiverImpl(final QueueImpl destination, + final SessionImpl session, + final String selector, + final boolean noLocal) + throws JMSException + { + super(destination, session, selector, noLocal); + setQueueConsumer(true); + } + + protected Receiver createClientReceiver() throws JMSException + { + try + { + return getSession().getClientSession().createMovingReceiver(getDestination().getAddress()); + } + catch (AmqpErrorException e) + { + throw new JMSException(e.getMessage(), e.getError().getCondition().toString()); + } + } + + public Queue getQueue() throws JMSException + { + return (QueueImpl) getDestination(); + } + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSenderImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSenderImpl.java new file mode 100644 index 0000000000..b3db43801a --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSenderImpl.java @@ -0,0 +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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.QueueSender; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; + +public class QueueSenderImpl extends MessageProducerImpl implements QueueSender +{ + protected QueueSenderImpl(final Destination destination, final SessionImpl session) + throws JMSException + { + super(destination, session); + } + + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSessionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSessionImpl.java new file mode 100644 index 0000000000..e5ed8b3b3d --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSessionImpl.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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.QueueSession; + +import javax.jms.JMSException; +import javax.jms.Queue; + +public class QueueSessionImpl extends SessionImpl implements QueueSession +{ + protected QueueSessionImpl(final ConnectionImpl connection, final AcknowledgeMode acknowledgeMode) + { + super(connection, acknowledgeMode); + setQueueSession(true); + } + + public QueueReceiverImpl createReceiver(final Queue queue) throws JMSException + { + return createReceiver(queue, null); + } + + public QueueReceiverImpl createReceiver(final Queue queue, final String selector) throws JMSException + { + // TODO - assert queue is a queueimpl and throw relevant JMS Exception + final QueueReceiverImpl messageConsumer; + synchronized(getClientSession().getEndpoint().getLock()) + { + messageConsumer = new QueueReceiverImpl((QueueImpl)queue, this, selector, false); + addConsumer(messageConsumer); + } + return messageConsumer; + + } + + public QueueSenderImpl createSender(final Queue queue) throws JMSException + { + return null; //TODO + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java new file mode 100644 index 0000000000..e321245a0e --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java @@ -0,0 +1,898 @@ +/* + * 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.amqp_1_0.jms.impl; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.UUID; +import javax.jms.BytesMessage; +import javax.jms.Destination; +import javax.jms.IllegalStateException; +import javax.jms.InvalidDestinationException; +import javax.jms.JMSException; +import javax.jms.MapMessage; +import javax.jms.MessageEOFException; +import javax.jms.MessageListener; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.StreamMessage; +import javax.jms.TextMessage; +import javax.jms.Topic; +import org.apache.qpid.amqp_1_0.client.Connection; +import org.apache.qpid.amqp_1_0.client.Message; +import org.apache.qpid.amqp_1_0.client.Receiver; +import org.apache.qpid.amqp_1_0.client.Sender; +import org.apache.qpid.amqp_1_0.client.Transaction; +import org.apache.qpid.amqp_1_0.jms.QueueReceiver; +import org.apache.qpid.amqp_1_0.jms.QueueSender; +import org.apache.qpid.amqp_1_0.jms.QueueSession; +import org.apache.qpid.amqp_1_0.jms.Session; +import org.apache.qpid.amqp_1_0.jms.TemporaryDestination; +import org.apache.qpid.amqp_1_0.jms.TopicPublisher; +import org.apache.qpid.amqp_1_0.jms.TopicSession; +import org.apache.qpid.amqp_1_0.jms.TopicSubscriber; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.messaging.Source; +import org.apache.qpid.amqp_1_0.type.messaging.Target; +import org.apache.qpid.amqp_1_0.type.transport.AmqpError; + +public class SessionImpl implements Session, QueueSession, TopicSession +{ + private ConnectionImpl _connection; + private AcknowledgeMode _acknowledgeMode; + private org.apache.qpid.amqp_1_0.client.Session _session; + private MessageFactory _messageFactory; + private List _consumers = new ArrayList(); + private List _producers = new ArrayList(); + + private MessageListener _messageListener; + private Dispatcher _dispatcher = new Dispatcher(); + private Thread _dispatcherThread; + + private boolean _closed; + + private boolean _isQueueSession; + private boolean _isTopicSession; + private Transaction _txn; + + protected SessionImpl(final ConnectionImpl connection, final AcknowledgeMode acknowledgeMode) + { + _connection = connection; + _acknowledgeMode = acknowledgeMode; + Connection clientConn = _connection.getClientConnection(); + _session = clientConn.createSession(); + if(_acknowledgeMode == AcknowledgeMode.SESSION_TRANSACTED) + { + _txn = _session.createSessionLocalTransaction(); + } + + _messageFactory = new MessageFactory(this); + + _dispatcherThread = new Thread(_dispatcher); + _dispatcherThread.start(); + } + + public BytesMessageImpl createBytesMessage() throws IllegalStateException + { + checkClosed(); + return new BytesMessageImpl(this); + + } + + public MapMessageImpl createMapMessage() throws JMSException + { + checkClosed(); + return new MapMessageImpl(this); + } + + public MessageImpl createMessage() throws IllegalStateException + { + return createAmqpMessage(); + } + + public ObjectMessageImpl createObjectMessage() throws JMSException + { + checkClosed(); + return new ObjectMessageImpl(this); + } + + public ObjectMessageImpl createObjectMessage(final Serializable serializable) throws JMSException + { + checkClosed(); + ObjectMessageImpl msg = new ObjectMessageImpl(this); + msg.setObject(serializable); + return msg; + } + + public StreamMessageImpl createStreamMessage() throws JMSException + { + checkClosed(); + return new StreamMessageImpl(this); + } + + public TextMessageImpl createTextMessage() throws JMSException + { + return createTextMessage(""); + } + + public TextMessageImpl createTextMessage(final String s) throws JMSException + { + checkClosed(); + TextMessageImpl msg = new TextMessageImpl(this); + msg.setText(s); + return msg; + } + + public AmqpMessageImpl createAmqpMessage() throws IllegalStateException + { + checkClosed(); + return new AmqpMessageImpl(this); + } + + public boolean getTransacted() throws JMSException + { + checkClosed(); + return _acknowledgeMode == AcknowledgeMode.SESSION_TRANSACTED; + } + + public int getAcknowledgeMode() throws IllegalStateException + { + checkClosed(); + return _acknowledgeMode.ordinal(); + } + + AcknowledgeMode getAckModeEnum() + { + return _acknowledgeMode; + } + + public void commit() throws JMSException + { + checkClosed(); + checkTransactional(); + + _txn.commit(); + for(MessageConsumerImpl consumer : _consumers) + { + consumer.postCommit(); + } + + _txn = _session.createSessionLocalTransaction(); + //TODO + } + + public void rollback() throws JMSException + { + checkClosed(); + checkTransactional(); + + _txn.rollback(); + + for(MessageConsumerImpl consumer : _consumers) + { + consumer.postRollback(); + } + + _txn = _session.createSessionLocalTransaction(); + + //TODO + } + + private void checkTransactional() throws JMSException + { + if(!getTransacted()) + { + throw new IllegalStateException("Session must be transacted in order to perform this operation"); + } + } + + public void close() throws JMSException + { + if(!_closed) + { + _closed = true; + _dispatcher.close(); + for(MessageConsumerImpl consumer : _consumers) + { + consumer.close(); + } + for(MessageProducerImpl producer : _producers) + { + producer.close(); + } + _session.close(); + } + } + + private void checkClosed() throws IllegalStateException + { + if(_closed) + { + throw new IllegalStateException("Closed"); + } + } + + public void recover() throws JMSException + { + checkClosed(); + checkNotTransactional(); + + if(_acknowledgeMode == AcknowledgeMode.CLIENT_ACKNOWLEDGE) + { + synchronized(_session.getEndpoint().getLock()) + { + for(MessageConsumerImpl consumer : _consumers) + { + consumer.doRecover(); + } + } + } + else + { + if(Thread.currentThread() == _dispatcherThread) + { + _dispatcher.doRecover(); + } + } + + } + + private void checkNotTransactional() throws JMSException + { + + if(getTransacted()) + { + throw new IllegalStateException("This operation cannot be carried out on a transacted session"); + } + } + + public MessageListener getMessageListener() throws JMSException + { + return _messageListener; + } + + public void setMessageListener(final MessageListener messageListener) throws JMSException + { + if(_messageListener != null) + { + // TODO + } + else + { + _messageListener = messageListener; + } + } + + public void run() + { + //TODO + } + + public MessageProducerImpl createProducer(final Destination destination) throws JMSException + { + checkClosed(); + + final MessageProducerImpl messageProducer = new MessageProducerImpl(destination, this); + + _producers.add(messageProducer); + + return messageProducer; + } + + public MessageConsumerImpl createConsumer(final Destination destination) throws JMSException + { + checkClosed(); + return createConsumer(destination, null, false); + } + + public MessageConsumerImpl createConsumer(final Destination destination, final String selector) throws JMSException + { + checkClosed(); + return createConsumer(destination, selector, false); + } + + public MessageConsumerImpl createConsumer(final Destination destination, final String selector, final boolean noLocal) + throws JMSException + { + checkClosed(); + checkValidDestination(destination); + if(destination instanceof TemporaryDestination) + { + TemporaryDestination temporaryDestination = (TemporaryDestination) destination; + if(temporaryDestination.getSession() != this) + { + throw new JMSException("Cannot consume from a temporary destination created on another session"); + } + if(temporaryDestination.isDeleted()) + { + throw new IllegalStateException("Destination is deleted"); + } + } + final MessageConsumerImpl messageConsumer; + synchronized(_session.getEndpoint().getLock()) + { + messageConsumer = new MessageConsumerImpl(destination, this, selector, noLocal); + addConsumer(messageConsumer); + if(_connection.isStarted()) + { + messageConsumer.start(); + } + } + return messageConsumer; + } + + private void checkValidDestination(Destination destination) throws InvalidDestinationException + { + if (destination == null || !(destination instanceof DestinationImpl)) + { + throw new InvalidDestinationException("Invalid Destination"); + } + } + + + protected void addConsumer(final MessageConsumerImpl messageConsumer) + { + _consumers.add(messageConsumer); + } + + public QueueImpl createQueue(final String s) throws JMSException + { + checkClosed(); + checkNotTopicSession(); + return new QueueImpl(s); + } + + public QueueReceiver createReceiver(final Queue queue) throws JMSException + { + checkClosed(); + checkNotTopicSession(); + return createConsumer(queue); + } + + public QueueReceiver createReceiver(final Queue queue, final String selector) throws JMSException + { + checkClosed(); + checkNotTopicSession(); + return createConsumer(queue, selector); + } + + public QueueSender createSender(final Queue queue) throws JMSException + { + checkClosed(); + checkNotTopicSession(); + return createProducer(queue); + } + + public TopicImpl createTopic(final String s) throws JMSException + { + checkClosed(); + checkNotQueueSession(); + return new TopicImpl(s); + } + + public TopicSubscriber createSubscriber(final Topic topic) throws JMSException + { + checkClosed(); + checkNotQueueSession(); + return createConsumer(topic); + } + + public TopicSubscriber createSubscriber(final Topic topic, final String selector, final boolean noLocal) throws JMSException + { + checkClosed(); + checkNotQueueSession(); + return createConsumer(topic, selector, noLocal); + } + + public TopicSubscriberImpl createDurableSubscriber(final Topic topic, final String name) throws JMSException + { + checkClosed(); + checkNotQueueSession(); + return createDurableSubscriber(topic, name, null, false); + } + + private void checkNotQueueSession() throws IllegalStateException + { + if(_isQueueSession) + { + throw new IllegalStateException("Cannot perform this operation on a QueueSession"); + } + } + + + private void checkNotTopicSession() throws IllegalStateException + { + if(_isTopicSession) + { + throw new IllegalStateException("Cannot perform this operation on a TopicSession"); + } + } + + public TopicSubscriberImpl createDurableSubscriber(final Topic topic, final String name, final String selector, final boolean noLocal) + throws JMSException + { + checkClosed(); + checkNotQueueSession(); + if(!(topic instanceof TopicImpl)) + { + throw new InvalidDestinationException("invalid destination " + topic); + } + final TopicSubscriberImpl messageConsumer; + synchronized(_session.getEndpoint().getLock()) + { + messageConsumer = new TopicSubscriberImpl(name, true, (org.apache.qpid.amqp_1_0.jms.Topic) topic, this, + selector, + noLocal); + addConsumer(messageConsumer); + if(_connection.isStarted()) + { + messageConsumer.start(); + } + } + return messageConsumer; + } + + public TopicPublisher createPublisher(final Topic topic) throws JMSException + { + checkClosed(); + checkNotQueueSession(); + return createProducer(topic); + } + + public QueueBrowserImpl createBrowser(final Queue queue) throws JMSException + { + checkClosed(); + checkNotTopicSession(); + checkValidDestination(queue); + return createBrowser(queue, null); + } + + public QueueBrowserImpl createBrowser(final Queue queue, final String selector) throws JMSException + { + checkClosed(); + checkNotTopicSession(); + checkValidDestination(queue); + + return new QueueBrowserImpl((QueueImpl) queue, selector, this); + + } + + public TemporaryQueueImpl createTemporaryQueue() throws JMSException + { + checkClosed(); + checkNotTopicSession(); + try + { + Sender send = _session.createTemporaryQueueSender(); + + TemporaryQueueImpl tempQ = new TemporaryQueueImpl(((Target)send.getTarget()).getAddress(), send, this); + return tempQ; + } + catch (Sender.SenderCreationException e) + { + throw new JMSException("Unable to create temporary queue"); + } + } + + public TemporaryTopicImpl createTemporaryTopic() throws JMSException + { + checkClosed(); + checkNotQueueSession(); + try + { + Sender send = _session.createTemporaryQueueSender(); + + TemporaryTopicImpl tempQ = new TemporaryTopicImpl(((Target)send.getTarget()).getAddress(), send, this); + return tempQ; + } + catch (Sender.SenderCreationException e) + { + throw new JMSException("Unable to create temporary queue"); + } + } + + public void unsubscribe(final String s) throws JMSException + { + checkClosed(); + + checkNotQueueSession(); + + Target target = new Target(); + target.setAddress(UUID.randomUUID().toString()); + + try + { + Receiver receiver = new Receiver(getClientSession(), s, target, null, + org.apache.qpid.amqp_1_0.client.AcknowledgeMode.ALO, false); + + final org.apache.qpid.amqp_1_0.type.Source receiverSource = receiver.getSource(); + if(receiverSource instanceof Source) + { + Source source = (Source) receiverSource; + receiver.close(); + receiver = new Receiver(getClientSession(), s, target, source, + org.apache.qpid.amqp_1_0.client.AcknowledgeMode.ALO, false); + + } + receiver.close(); + } + catch(AmqpErrorException e) + { + if(e.getError().getCondition() == AmqpError.NOT_FOUND) + { + throw new InvalidDestinationException(s); + } + else + { + JMSException jmsException = new JMSException(e.getMessage()); + jmsException.setLinkedException(e); + throw jmsException; + } + } + + //TODO + } + + void stop() + { + //TODO + } + + void start() + { + _dispatcher.start(); + for(MessageConsumerImpl consumer : _consumers) + { + consumer.start(); + } + } + + org.apache.qpid.amqp_1_0.client.Session getClientSession() + { + return _session; + } + + public MessageFactory getMessageFactory() + { + return _messageFactory; + } + + void acknowledgeAll() throws IllegalStateException + { + synchronized(_session.getEndpoint().getLock()) + { + checkClosed(); + for(MessageConsumerImpl consumer : _consumers) + { + consumer.acknowledgeAll(); + } + } + } + + void messageListenerSet(final MessageConsumerImpl messageConsumer) + { + _dispatcher.updateMessageListener(messageConsumer); + } + + public void messageArrived(final MessageConsumerImpl messageConsumer) + { + _dispatcher.messageArrivedAtConsumer(messageConsumer); + } + + MessageImpl convertMessage(final javax.jms.Message message) throws JMSException + { + MessageImpl replacementMessage; + + if(message instanceof BytesMessage) + { + replacementMessage = convertBytesMessage((BytesMessage) message); + } + else + { + if(message instanceof MapMessage) + { + replacementMessage = convertMapMessage((MapMessage) message); + } + else + { + if(message instanceof ObjectMessage) + { + replacementMessage = convertObjectMessage((ObjectMessage) message); + } + else + { + if(message instanceof StreamMessage) + { + replacementMessage = convertStreamMessage((StreamMessage) message); + } + else + { + if(message instanceof TextMessage) + { + replacementMessage = convertTextMessage((TextMessage) message); + } + else + { + replacementMessage = createMessage(); + } + } + } + } + } + + convertMessageProperties(message, replacementMessage); + + return replacementMessage; + } + + + private void convertMessageProperties(final javax.jms.Message message, final MessageImpl replacementMessage) + throws JMSException + { + Enumeration propertyNames = message.getPropertyNames(); + while (propertyNames.hasMoreElements()) + { + String propertyName = String.valueOf(propertyNames.nextElement()); + // TODO: Shouldn't need to check for JMS properties here as don't think getPropertyNames() should return them + if (!propertyName.startsWith("JMSX_")) + { + Object value = message.getObjectProperty(propertyName); + replacementMessage.setObjectProperty(propertyName, value); + } + } + + + replacementMessage.setJMSDeliveryMode(message.getJMSDeliveryMode()); + + if (message.getJMSReplyTo() != null) + { + replacementMessage.setJMSReplyTo(message.getJMSReplyTo()); + } + + replacementMessage.setJMSType(message.getJMSType()); + + replacementMessage.setJMSCorrelationID(message.getJMSCorrelationID()); + } + + private MessageImpl convertMapMessage(final MapMessage message) throws JMSException + { + MapMessageImpl mapMessage = createMapMessage(); + + Enumeration mapNames = message.getMapNames(); + while (mapNames.hasMoreElements()) + { + String name = (String) mapNames.nextElement(); + mapMessage.setObject(name, message.getObject(name)); + } + + return mapMessage; + } + + private MessageImpl convertBytesMessage(final BytesMessage message) throws JMSException + { + BytesMessageImpl bytesMessage = createBytesMessage(); + + message.reset(); + + byte[] buf = new byte[1024]; + + int len; + + while ((len = message.readBytes(buf)) != -1) + { + bytesMessage.writeBytes(buf, 0, len); + } + + return bytesMessage; + } + + private MessageImpl convertObjectMessage(final ObjectMessage message) throws JMSException + { + ObjectMessageImpl objectMessage = createObjectMessage(); + objectMessage.setObject(message.getObject()); + return objectMessage; + } + + private MessageImpl convertStreamMessage(final StreamMessage message) throws JMSException + { + StreamMessageImpl streamMessage = createStreamMessage(); + + try + { + message.reset(); + while (true) + { + streamMessage.writeObject(message.readObject()); + } + } + catch (MessageEOFException e) + { + // we're at the end so don't mind the exception + } + + return streamMessage; + } + + private MessageImpl convertTextMessage(final TextMessage message) throws JMSException + { + return createTextMessage(message.getText()); + } + + ConnectionImpl getConnection() + { + return _connection; + } + + Transaction getTxn() + { + return _txn; + } + + + private class Dispatcher implements Runnable + { + + private final List _messageConsumerList = new ArrayList(); + + private boolean _closed; + private boolean _started; + + private Message _recoveredMessage; + private MessageConsumerImpl _recoveredConsumer; + private MessageConsumerImpl _currentConsumer; + private Message _currentMessage; + + public void run() + { + synchronized(getLock()) + { + while(!_closed) + { + while(!_started || (_recoveredMessage == null && _messageConsumerList.isEmpty())) + { + try + { + getLock().wait(); + } + catch (InterruptedException e) + { + return; + } + } + while(_started && (_recoveredMessage != null || !_messageConsumerList.isEmpty())) + { + Message msg; + + MessageConsumerImpl consumer; + + boolean recoveredMessage = _recoveredMessage != null; + if(recoveredMessage) + { + consumer = _recoveredConsumer; + msg = _recoveredMessage; + _recoveredMessage = null; + _recoveredConsumer = null; + } + else + { + consumer = _messageConsumerList.remove(0); + msg = consumer.receive0(0L); + } + + + MessageListener listener = consumer._messageListener; + + MessageImpl message = consumer.createJMSMessage(msg, recoveredMessage); + + if(message != null) + { + _currentConsumer = consumer; + _currentMessage = msg; + try + { + listener.onMessage(message); + } + finally + { + _currentConsumer = null; + _currentMessage = null; + } + + if((_recoveredMessage == null) && (_acknowledgeMode == AcknowledgeMode.AUTO_ACKNOWLEDGE + || _acknowledgeMode == AcknowledgeMode.DUPS_OK_ACKNOWLEDGE)) + { + consumer.acknowledge(msg); + } + } + + } + + + } + } + } + + private Object getLock() + { + return _session.getEndpoint().getLock(); + } + + public void messageArrivedAtConsumer(MessageConsumerImpl impl) + { + synchronized (getLock()) + { + _messageConsumerList.add(impl); + getLock().notifyAll(); + } + } + + public void close() + { + synchronized (getLock()) + { + _closed = true; + getLock().notifyAll(); + } + } + + public void updateMessageListener(final MessageConsumerImpl messageConsumer) + { + synchronized (getLock()) + { + getLock().notifyAll(); + } + } + + public void start() + { + synchronized (getLock()) + { + _started = true; + getLock().notifyAll(); + } + } + + public void stop() + { + synchronized (getLock()) + { + _started = false; + getLock().notifyAll(); + } + } + + public void doRecover() + { + _recoveredConsumer = _currentConsumer; + _recoveredMessage = _currentMessage; + } + } + + void setQueueSession(final boolean queueSession) + { + _isQueueSession = queueSession; + } + + void setTopicSession(final boolean topicSession) + { + _isTopicSession = topicSession; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java new file mode 100644 index 0000000000..8275de884e --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java @@ -0,0 +1,466 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.StreamMessage; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import javax.jms.JMSException; +import javax.jms.MessageEOFException; +import javax.jms.MessageFormatException; +import java.io.EOFException; +import java.util.*; + +public class StreamMessageImpl extends MessageImpl implements StreamMessage +{ + private List _list; + private boolean _readOnly; + private int _position = -1; + private int _offset = -1; + + + + protected StreamMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, List list, + Footer footer, SessionImpl session) + { + super(header, messageAnnotations, properties, appProperties, footer, session); + _list = list; + } + + StreamMessageImpl(final SessionImpl session) + { + super(new Header(), new MessageAnnotations(new HashMap()), new Properties(), + new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP), + session); + _list = new ArrayList(); + } + + public StreamMessageImpl(final Header header, + final MessageAnnotations messageAnnotations, + final Properties properties, + final ApplicationProperties appProperties, + final List amqpListSection, final Footer footer) + { + super(header, messageAnnotations, properties, appProperties, footer, null); + _list = amqpListSection; + } + + public boolean readBoolean() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Boolean) + { + return (Boolean) obj; + } + if(obj instanceof String || obj == null) + { + return Boolean.valueOf((String)obj); + } + else + { + throw new MessageFormatException("Cannot read " + obj.getClass().getName() + " as boolean"); + } + } + + @Override + public void clearBody() throws JMSException + { + super.clearBody(); + _list.clear(); + _position = -1; + _offset = -1; + } + + public byte readByte() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Byte) + { + return (Byte) obj; + } + else if(obj instanceof String || obj == null) + { + try + { + return Byte.valueOf((String)obj); + } + catch(RuntimeException e) + { + backup(); + throw e; + } + } + else + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + } + + private void backup() + { + _position--; + } + + public short readShort() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Short) + { + return (Short) obj; + } + else if(obj instanceof Byte) + { + return (Byte) obj; + } + else if(obj instanceof String || obj == null) + { + try + { + return Short.valueOf((String)obj); + } + catch(RuntimeException e) + { + backup(); + throw e; + } + } + else + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + + } + + public char readChar() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Character) + { + return (Character) obj; + } + if(obj == null) + { + backup(); + throw new NullPointerException(); + } + else + { + backup(); + throw new MessageFormatException("Cannot read " + obj.getClass().getName() + " as boolean"); + } + + } + + public int readInt() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Integer) + { + return (Integer) obj; + } + else if(obj instanceof Short) + { + return (Short) obj; + } + else if(obj instanceof Byte) + { + return (Byte) obj; + } + else if(obj instanceof String || obj == null) + { + try + { + return Integer.valueOf((String)obj); + } + catch (RuntimeException e) + { + backup(); + throw e; + } + } + else + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + } + + public long readLong() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Long) + { + return (Long) obj; + } + else if(obj instanceof Integer) + { + return (Integer) obj; + } + else if(obj instanceof Short) + { + return (Short) obj; + } + else if(obj instanceof Byte) + { + return (Byte) obj; + } + else if(obj instanceof String || obj == null) + { + try + { + return Long.valueOf((String)obj); + } + catch (RuntimeException e) + { + backup(); + throw e; + } + } + else + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + } + + public float readFloat() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Float) + { + return (Float) obj; + } + else if(obj instanceof String || obj == null) + { + try + { + return Float.valueOf((String)obj); + } + catch (RuntimeException e) + { + backup(); + throw e; + } + } + else + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + } + + public double readDouble() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Double) + { + return (Double) obj; + } + else if(obj instanceof Float) + { + return (Float) obj; + } + else if(obj instanceof String || obj == null) + { + try + { + return Double.valueOf((String)obj); + } + catch (RuntimeException e) + { + backup(); + throw e; + } + } + else + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + } + + public String readString() throws JMSException + { + Object obj = readObject(); + if(obj instanceof Binary) + { + backup(); + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + return String.valueOf(obj); + } + + public int readBytes(final byte[] bytes) throws JMSException + { + Object obj = readObject(); + if(!(obj instanceof Binary)) + { + backup(); + if(_position > -1 && _list.get(_position) instanceof Binary) + { + return -1; + } + throw new MessageFormatException("Cannot convert value of type " + obj.getClass().getName()); + } + Binary binary = (Binary) obj; + if(bytes.length >= binary.getLength()) + { + System.arraycopy(binary.getArray(),binary.getArrayOffset(),bytes,0,binary.getLength()); + return binary.getLength(); + } + return -1; + } + + public Object readObject() throws JMSException + { + checkReadable(); + if(_offset == -1) + { + try + { + return _list.get(++_position); + } + catch (IndexOutOfBoundsException e) + { + throw new MessageEOFException("No more data in message stream"); + } + } + else + { + return null; //TODO + } + } + + public void writeBoolean(final boolean b) throws JMSException + { + checkWritable(); + _list.add(b); + } + + public void writeByte(final byte b) throws JMSException + { + checkWritable(); + _list.add(b); + } + + public void writeShort(final short i) throws JMSException + { + checkWritable(); + _list.add(i); + } + + public void writeChar(final char c) throws JMSException + { + checkWritable(); + _list.add(c); + } + + public void writeInt(final int i) throws JMSException + { + checkWritable(); + _list.add(i); + } + + public void writeLong(final long l) throws JMSException + { + checkWritable(); + _list.add(l); + } + + public void writeFloat(final float v) throws JMSException + { + checkWritable(); + _list.add(v); + } + + public void writeDouble(final double v) throws JMSException + { + checkWritable(); + _list.add(v); + } + + public void writeString(final String s) throws JMSException + { + checkWritable(); + _list.add(s); + } + + public void writeBytes(final byte[] bytes) throws JMSException + { + checkWritable(); + writeBytes(bytes, 0, bytes.length); + } + + public void writeBytes(final byte[] bytes, final int offset, final int size) throws JMSException + { + checkWritable(); + + if(!_list.isEmpty() && _list.get(_list.size()-1) instanceof byte[]) + { + Binary oldVal = (Binary) _list.get(_list.size()-1); + byte[] allBytes = new byte[oldVal.getLength() + size]; + System.arraycopy(oldVal.getArray(),oldVal.getArrayOffset(),allBytes,0,oldVal.getLength()); + System.arraycopy(bytes, offset, allBytes, oldVal.getLength(), size); + _list.set(_list.size()-1, allBytes); + } + else + { + byte[] dup = new byte[size]; + System.arraycopy(bytes,offset,dup,0,size); + _list.add(new Binary(dup)); + } + } + + public void writeObject(final Object o) throws JMSException + { + checkWritable(); + if(o == null || _supportedClasses.contains(o.getClass())) + { + _list.add(o); + } + } + + public void reset() throws JMSException + { + super.reset(); + _position = -1; + _offset = -1; + } + + @Override Collection
getSections() + { + List
sections = new ArrayList
(); + sections.add(getHeader()); + if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty()) + { + sections.add(getMessageAnnotations()); + } + sections.add(getProperties()); + sections.add(getApplicationProperties()); + sections.add(new AmqpValue(_list)); + sections.add(getFooter()); + return sections; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryQueueImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryQueueImpl.java new file mode 100644 index 0000000000..76608c421b --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryQueueImpl.java @@ -0,0 +1,105 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.Sender; +import org.apache.qpid.amqp_1_0.jms.MessageConsumer; +import org.apache.qpid.amqp_1_0.jms.TemporaryQueue; + +import javax.jms.IllegalStateException; +import javax.jms.JMSException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class TemporaryQueueImpl extends QueueImpl implements TemporaryQueue +{ + private Sender _sender; + private SessionImpl _session; + private final Set _consumers = + Collections.synchronizedSet(new HashSet()); + + protected TemporaryQueueImpl(String address, Sender sender, SessionImpl session) + { + super(address); + _sender = sender; + _session = session; + _session.getConnection().addOnCloseTask(new ConnectionImpl.CloseTask() + { + public void onClose() throws JMSException + { + synchronized (TemporaryQueueImpl.this) + { + close(); + } + } + }); + } + + public synchronized void delete() throws JMSException + { + if(_consumers.isEmpty()) + { + close(); + } + else + { + throw new IllegalStateException("Cannot delete destination as it has consumers"); + } + } + + private void close() throws JMSException + { + if(_sender != null) + { + try + { + _sender.close(); + _sender = null; + } + catch (Sender.SenderClosingException e) + { + final JMSException jmsException = new JMSException(e.getMessage()); + jmsException.setLinkedException(e); + throw jmsException; + } + } + + } + + public SessionImpl getSession() + { + return _session; + } + + public void addConsumer(MessageConsumer consumer) + { + _consumers.add(consumer); + } + + public void removeConsumer(MessageConsumer consumer) + { + _consumers.remove(consumer); + } + + public boolean isDeleted() + { + return _sender == null; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryTopicImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryTopicImpl.java new file mode 100644 index 0000000000..8e0d07e78b --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryTopicImpl.java @@ -0,0 +1,110 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.Sender; +import org.apache.qpid.amqp_1_0.jms.MessageConsumer; +import org.apache.qpid.amqp_1_0.jms.TemporaryTopic; + +import javax.jms.IllegalStateException; +import javax.jms.JMSException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public class TemporaryTopicImpl extends TopicImpl implements TemporaryTopic +{ + private Sender _sender; + private SessionImpl _session; + private final Set _consumers = + Collections.synchronizedSet(new HashSet()); + + protected TemporaryTopicImpl(String address, Sender sender, SessionImpl session) + { + super(address); + _sender = sender; + _session = session; + + _session.getConnection().addOnCloseTask(new ConnectionImpl.CloseTask() + { + public void onClose() throws JMSException + { + synchronized (TemporaryTopicImpl.this) + { + close(); + } + } + }); + } + + public void delete() throws JMSException + { + if(_consumers.isEmpty()) + { + close(); + } + else + { + throw new IllegalStateException("Cannot delete destination as it has consumers"); + } + + } + + + private void close() throws JMSException + { + if(_sender != null) + { + try + { + + _sender.close(); + _sender = null; + } + catch (Sender.SenderClosingException e) + { + final JMSException jmsException = new JMSException(e.getMessage()); + jmsException.setLinkedException(e); + throw jmsException; + } + } + + } + + public SessionImpl getSession() + { + return _session; + } + + + public void addConsumer(MessageConsumer consumer) + { + _consumers.add(consumer); + } + + public void removeConsumer(MessageConsumer consumer) + { + _consumers.remove(consumer); + } + + public boolean isDeleted() + { + return _sender == null; + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java new file mode 100644 index 0000000000..5d9172229c --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java @@ -0,0 +1,93 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.TextMessage; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import javax.jms.JMSException; +import javax.jms.MessageNotWriteableException; +import java.util.*; + +public class TextMessageImpl extends MessageImpl implements TextMessage +{ + private String _text; + + protected TextMessageImpl(Header header, + MessageAnnotations messageAnnotations, + Properties properties, + ApplicationProperties appProperties, + String text, + Footer footer, + SessionImpl session) + { + super(header, messageAnnotations, properties, appProperties, footer, session); + _text = text; + } + + protected TextMessageImpl(final SessionImpl session) + { + super(new Header(), new MessageAnnotations(new HashMap()), + new Properties(), new ApplicationProperties(new HashMap()), new Footer(Collections.EMPTY_MAP), + session); + } + + public void setText(final String text) throws MessageNotWriteableException + { + if(isReadOnly()) + { + throw new MessageNotWriteableException("Cannot set object, message is in read only mode"); + } + + _text = text; + } + + public String getText() throws JMSException + { + return _text; + } + + @Override + public void clearBody() throws JMSException + { + super.clearBody(); + _text = null; + } + + @Override Collection
getSections() + { + List
sections = new ArrayList
(); + sections.add(getHeader()); + if(getMessageAnnotations() != null && getMessageAnnotations().getValue() != null && !getMessageAnnotations().getValue().isEmpty()) + { + sections.add(getMessageAnnotations()); + } + sections.add(getProperties()); + sections.add(getApplicationProperties()); + AmqpValue section = new AmqpValue(_text); + sections.add(section); + sections.add(getFooter()); + return sections; + } + + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicConnectionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicConnectionImpl.java new file mode 100644 index 0000000000..de456532cb --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicConnectionImpl.java @@ -0,0 +1,48 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.TopicConnection; + +import javax.jms.ConnectionConsumer; +import javax.jms.JMSException; +import javax.jms.ServerSessionPool; +import javax.jms.Topic; + +public class TopicConnectionImpl extends ConnectionImpl implements TopicConnection +{ + TopicConnectionImpl(String host, int port, String username, String password, String clientId) + throws JMSException + { + super(host, port, username, password, clientId); + } + + public TopicSessionImpl createTopicSession(final boolean b, final int i) throws JMSException + { + return null; //TODO + } + + public ConnectionConsumer createConnectionConsumer(final Topic topic, + final String s, + final ServerSessionPool serverSessionPool, + final int i) throws JMSException + { + return null; //TODO + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicImpl.java new file mode 100644 index 0000000000..e54a660963 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicImpl.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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.Topic; + +import java.util.WeakHashMap; + +public class TopicImpl extends DestinationImpl implements Topic +{ + private static final WeakHashMap TOPIC_CACHE = + new WeakHashMap(); + + + public TopicImpl(String address) + { + super(address); + } + + public String getTopicName() + { + return getAddress(); + } + + public static synchronized TopicImpl createTopic(final String address) + { + TopicImpl topic = TOPIC_CACHE.get(address); + if(topic == null) + { + topic = new TopicImpl(address); + TOPIC_CACHE.put(address, topic); + } + return topic; + } + + public static TopicImpl valueOf(String address) + { + return address == null ? null : createTopic(address); + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicPublisherImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicPublisherImpl.java new file mode 100644 index 0000000000..a2d2f34043 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicPublisherImpl.java @@ -0,0 +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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.TopicPublisher; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.Topic; + +public class TopicPublisherImpl extends MessageProducerImpl implements TopicPublisher +{ + protected TopicPublisherImpl(final Destination destination, final SessionImpl session) + throws JMSException + { + super(destination, session); + } + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSessionImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSessionImpl.java new file mode 100644 index 0000000000..052a3f2a6b --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSessionImpl.java @@ -0,0 +1,55 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.jms.TopicSession; + +import javax.jms.JMSException; +import javax.jms.Topic; + +public class TopicSessionImpl extends SessionImpl implements TopicSession +{ + protected TopicSessionImpl(final ConnectionImpl connection, final AcknowledgeMode acknowledgeMode) + { + super(connection, acknowledgeMode); + setTopicSession(true); + } + + public TopicSubscriberImpl createSubscriber(final Topic topic) throws JMSException + { + return createSubscriber(topic,null, false); + } + + public TopicSubscriberImpl createSubscriber(final Topic topic, final String selector, final boolean noLocal) throws JMSException + { + + final TopicSubscriberImpl messageConsumer; + synchronized(getClientSession().getEndpoint().getLock()) + { + messageConsumer = new TopicSubscriberImpl((TopicImpl) topic, this, selector, noLocal); + addConsumer(messageConsumer); + } + return messageConsumer; + } + + public TopicPublisherImpl createPublisher(final Topic topic) throws JMSException + { + return null; //TODO + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java new file mode 100644 index 0000000000..52d8c412ec --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java @@ -0,0 +1,133 @@ +/* + * 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.amqp_1_0.jms.impl; + +import org.apache.qpid.amqp_1_0.client.AcknowledgeMode; +import org.apache.qpid.amqp_1_0.client.Receiver; +import org.apache.qpid.amqp_1_0.jms.Topic; +import org.apache.qpid.amqp_1_0.jms.TopicSubscriber; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.Filter; +import org.apache.qpid.amqp_1_0.type.messaging.StdDistMode; +import org.apache.qpid.amqp_1_0.type.transport.*; + +import javax.jms.*; +import java.util.Map; + +public class TopicSubscriberImpl extends MessageConsumerImpl implements TopicSubscriber +{ + + TopicSubscriberImpl(String name, + boolean durable, + final Topic destination, + final SessionImpl session, + final String selector, + final boolean noLocal) + throws JMSException + { + super(destination, session, selector, noLocal, name, durable); + setTopicSubscriber(true); + } + + TopicSubscriberImpl(final Topic destination, + final SessionImpl session, + final String selector, + final boolean noLocal) + throws JMSException + { + super(destination, session, selector, noLocal); + setTopicSubscriber(true); + } + + public TopicImpl getTopic() throws JMSException + { + return (TopicImpl) getDestination(); + } + + + protected Receiver createClientReceiver() throws JMSException + { + try + { + String address = getDestination().getAddress(); + Receiver receiver = getSession().getClientSession().createReceiver(address, + StdDistMode.COPY, AcknowledgeMode.ALO, + getLinkName(), isDurable(), getFilters(), + null); + String actualAddress = receiver.getAddress(); + + @SuppressWarnings("unchecked") + Map actualFilters = (Map) receiver.getFilter(); + + if(!address.equals(actualAddress) || !filtersEqual(getFilters(), actualFilters)) + { + receiver.close(); + if(isDurable()) + { + receiver = getSession().getClientSession().createReceiver(address, + StdDistMode.COPY, AcknowledgeMode.ALO, + getLinkName(), false, getFilters(), + null); + receiver.close(); + } + receiver = getSession().getClientSession().createReceiver(address, + StdDistMode.COPY, AcknowledgeMode.ALO, + getLinkName(), isDurable(), getFilters(), + null); + } + + + return receiver; + } + catch (AmqpErrorException e) + { + org.apache.qpid.amqp_1_0.type.transport.Error error = e.getError(); + if(AmqpError.INVALID_FIELD.equals(error.getCondition())) + { + throw new InvalidSelectorException(e.getMessage()); + } + else + { + throw new JMSException(e.getMessage(), error.getCondition().getValue().toString()); + + } + + } + } + + private boolean filtersEqual(Map filters, Map actualFilters) + { + if(filters == null || filters.isEmpty()) + { + return actualFilters == null || actualFilters.isEmpty(); + } + else + { + return actualFilters != null && filters.equals(actualFilters); + } + + } + + + protected void closeUnderlyingReceiver(Receiver receiver) + { + receiver.close(); + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/NameParserImpl.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/NameParserImpl.java new file mode 100644 index 0000000000..7c3857f6c9 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/NameParserImpl.java @@ -0,0 +1,37 @@ +/** + * + * 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.amqp_1_0.jms.jndi; + +import javax.naming.CompositeName; +import javax.naming.Name; +import javax.naming.NameParser; +import javax.naming.NamingException; + +/** + * A default implementation of {@link NameParser} + *

+ * Based on class from ActiveMQ. + */ +public class NameParserImpl implements NameParser +{ + public Name parse(String name) throws NamingException + { + return new CompositeName(name); + } +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java new file mode 100644 index 0000000000..31030a7d30 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java @@ -0,0 +1,230 @@ +/* + * + * 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.amqp_1_0.jms.jndi; + +import org.apache.qpid.amqp_1_0.jms.impl.ConnectionFactoryImpl; +import org.apache.qpid.amqp_1_0.jms.impl.DestinationImpl; +import org.apache.qpid.amqp_1_0.jms.impl.QueueImpl; +import org.apache.qpid.amqp_1_0.jms.impl.TopicImpl; + +import java.io.BufferedInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.Queue; +import javax.jms.Topic; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.spi.InitialContextFactory; + + +public class PropertiesFileInitialContextFactory implements InitialContextFactory +{ + + private String CONNECTION_FACTORY_PREFIX = "connectionfactory."; + private String DESTINATION_PREFIX = "destination."; + private String QUEUE_PREFIX = "queue."; + private String TOPIC_PREFIX = "topic."; + + public Context getInitialContext(Hashtable environment) throws NamingException + { + Map data = new ConcurrentHashMap(); + + String file = null; + try + { + + + if (environment.containsKey(Context.PROVIDER_URL)) + { + file = (String) environment.get(Context.PROVIDER_URL); + } + else + { + file = System.getProperty(Context.PROVIDER_URL); + } + + if (file != null) + { + + // Load the properties specified + BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file)); + Properties p = new Properties(); + try + { + p.load(inputStream); + } + finally + { + inputStream.close(); + } + + + for (Map.Entry me : p.entrySet()) + { + String key = (String) me.getKey(); + String value = (String) me.getValue(); + environment.put(key, value); + if (System.getProperty(key) == null) + { + System.setProperty(key, value); + } + } + } + else + { + throw new NamingException("No Provider URL specified."); + } + } + catch (IOException ioe) + { + NamingException ne = new NamingException("Unable to load property file:" + file +"."); + ne.setRootCause(ioe); + throw ne; + } + + try + { + createConnectionFactories(data, environment); + } + catch (MalformedURLException e) + { + NamingException ne = new NamingException(); + ne.setRootCause(e); + throw ne; + } + + createDestinations(data, environment); + + createQueues(data, environment); + + createTopics(data, environment); + + return createContext(data, environment); + } + + protected ReadOnlyContext createContext(Map data, Hashtable environment) + { + return new ReadOnlyContext(environment, data); + } + + protected void createConnectionFactories(Map data, Hashtable environment) throws MalformedURLException + { + for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) + { + Map.Entry entry = (Map.Entry) iter.next(); + String key = entry.getKey().toString(); + if (key.startsWith(CONNECTION_FACTORY_PREFIX)) + { + String jndiName = key.substring(CONNECTION_FACTORY_PREFIX.length()); + ConnectionFactory cf = createFactory(entry.getValue().toString().trim()); + if (cf != null) + { + data.put(jndiName, cf); + } + } + } + } + + protected void createDestinations(Map data, Hashtable environment) + { + for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) + { + Map.Entry entry = (Map.Entry) iter.next(); + String key = entry.getKey().toString(); + if (key.startsWith(DESTINATION_PREFIX)) + { + String jndiName = key.substring(DESTINATION_PREFIX.length()); + Destination dest = createDestination(entry.getValue().toString().trim()); + if (dest != null) + { + data.put(jndiName, dest); + } + } + } + } + + protected void createQueues(Map data, Hashtable environment) + { + for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) + { + Map.Entry entry = (Map.Entry) iter.next(); + String key = entry.getKey().toString(); + if (key.startsWith(QUEUE_PREFIX)) + { + String jndiName = key.substring(QUEUE_PREFIX.length()); + Queue q = createQueue(entry.getValue().toString().trim()); + if (q != null) + { + data.put(jndiName, q); + } + } + } + } + + protected void createTopics(Map data, Hashtable environment) + { + for (Iterator iter = environment.entrySet().iterator(); iter.hasNext();) + { + Map.Entry entry = (Map.Entry) iter.next(); + String key = entry.getKey().toString(); + if (key.startsWith(TOPIC_PREFIX)) + { + String jndiName = key.substring(TOPIC_PREFIX.length()); + Topic t = createTopic(entry.getValue().toString().trim()); + if (t != null) + { + data.put(jndiName, t); + } + } + } + } + + + private ConnectionFactory createFactory(String url) throws MalformedURLException + { + return ConnectionFactoryImpl.createFromURL(url); + } + + private DestinationImpl createDestination(String str) + { + return DestinationImpl.createDestination(str); + } + + private QueueImpl createQueue(String address) + { + return QueueImpl.createQueue(address); + } + + private TopicImpl createTopic(String address) + { + return TopicImpl.createTopic(address); + } + +} diff --git a/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/ReadOnlyContext.java b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/ReadOnlyContext.java new file mode 100644 index 0000000000..4e0f994b94 --- /dev/null +++ b/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/ReadOnlyContext.java @@ -0,0 +1,527 @@ +/* + * + * 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.amqp_1_0.jms.jndi; + +import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +import javax.naming.Binding; +import javax.naming.CompositeName; +import javax.naming.Context; +import javax.naming.LinkRef; +import javax.naming.Name; +import javax.naming.NameClassPair; +import javax.naming.NameNotFoundException; +import javax.naming.NameParser; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.NotContextException; +import javax.naming.OperationNotSupportedException; +import javax.naming.Reference; +import javax.naming.spi.NamingManager; + +/** + * Based on class from ActiveMQ. + * A read-only Context + *

+ * This version assumes it and all its subcontext are read-only and any attempt + * to modify (e.g. through bind) will result in an OperationNotSupportedException. + * Each Context in the tree builds a cache of the entries in all sub-contexts + * to optimise the performance of lookup. + *

+ *

This implementation is intended to optimise the performance of lookup(String) + * to about the level of a HashMap get. It has been observed that the scheme + * resolution phase performed by the JVM takes considerably longer, so for + * optimum performance lookups should be coded like:

+ * + * Context componentContext = (Context)new InitialContext().lookup("java:comp"); + * String envEntry = (String) componentContext.lookup("env/myEntry"); + * String envEntry2 = (String) componentContext.lookup("env/myEntry2"); + * + */ +public class ReadOnlyContext implements Context, Serializable +{ + private static final long serialVersionUID = -5754338187296859149L; + protected static final NameParser nameParser = new NameParserImpl(); + + protected final Hashtable environment; // environment for this context + protected final Map bindings; // bindings at my level + protected final Map treeBindings; // all bindings under me + + private boolean frozen = false; + private String nameInNamespace = ""; + public static final String SEPARATOR = "/"; + + public ReadOnlyContext() + { + environment = new Hashtable(); + bindings = new HashMap(); + treeBindings = new HashMap(); + } + + public ReadOnlyContext(Hashtable env) + { + if (env == null) + { + this.environment = new Hashtable(); + } + else + { + this.environment = new Hashtable(env); + } + + this.bindings = Collections.EMPTY_MAP; + this.treeBindings = Collections.EMPTY_MAP; + } + + public ReadOnlyContext(Hashtable environment, Map bindings) + { + if (environment == null) + { + this.environment = new Hashtable(); + } + else + { + this.environment = new Hashtable(environment); + } + + this.bindings = bindings; + treeBindings = new HashMap(); + frozen = true; + } + + public ReadOnlyContext(Hashtable environment, Map bindings, String nameInNamespace) + { + this(environment, bindings); + this.nameInNamespace = nameInNamespace; + } + + protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env) + { + this.bindings = clone.bindings; + this.treeBindings = clone.treeBindings; + this.environment = new Hashtable(env); + } + + protected ReadOnlyContext(ReadOnlyContext clone, Hashtable env, String nameInNamespace) + { + this(clone, env); + this.nameInNamespace = nameInNamespace; + } + + public void freeze() + { + frozen = true; + } + + boolean isFrozen() + { + return frozen; + } + + /** + * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses. + * It binds every possible lookup into a map in each context. To do this, each context + * strips off one name segment and if necessary creates a new context for it. Then it asks that context + * to bind the remaining name. It returns a map containing all the bindings from the next context, plus + * the context it just created (if it in fact created it). (the names are suitably extended by the segment + * originally lopped off). + * + * @param name + * @param value + * @return + * @throws javax.naming.NamingException + */ + protected Map internalBind(String name, Object value) throws NamingException + { + assert (name != null) && (name.length() > 0); + assert !frozen; + + Map newBindings = new HashMap(); + int pos = name.indexOf('/'); + if (pos == -1) + { + if (treeBindings.put(name, value) != null) + { + throw new NamingException("Something already bound at " + name); + } + + bindings.put(name, value); + newBindings.put(name, value); + } + else + { + String segment = name.substring(0, pos); + assert segment != null; + assert !segment.equals(""); + Object o = treeBindings.get(segment); + if (o == null) + { + o = newContext(); + treeBindings.put(segment, o); + bindings.put(segment, o); + newBindings.put(segment, o); + } + else if (!(o instanceof ReadOnlyContext)) + { + throw new NamingException("Something already bound where a subcontext should go"); + } + + ReadOnlyContext readOnlyContext = (ReadOnlyContext) o; + String remainder = name.substring(pos + 1); + Map subBindings = readOnlyContext.internalBind(remainder, value); + for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();) + { + Map.Entry entry = (Map.Entry) iterator.next(); + String subName = segment + "/" + (String) entry.getKey(); + Object bound = entry.getValue(); + treeBindings.put(subName, bound); + newBindings.put(subName, bound); + } + } + + return newBindings; + } + + protected ReadOnlyContext newContext() + { + return new ReadOnlyContext(); + } + + public Object addToEnvironment(String propName, Object propVal) throws NamingException + { + return environment.put(propName, propVal); + } + + public Hashtable getEnvironment() throws NamingException + { + return (Hashtable) environment.clone(); + } + + public Object removeFromEnvironment(String propName) throws NamingException + { + return environment.remove(propName); + } + + public Object lookup(String name) throws NamingException + { + if (name.length() == 0) + { + return this; + } + + Object result = treeBindings.get(name); + if (result == null) + { + result = bindings.get(name); + } + + if (result == null) + { + int pos = name.indexOf(':'); + if (pos > 0) + { + String scheme = name.substring(0, pos); + Context ctx = NamingManager.getURLContext(scheme, environment); + if (ctx == null) + { + throw new NamingException("scheme " + scheme + " not recognized"); + } + + return ctx.lookup(name); + } + else + { + // Split out the first name of the path + // and look for it in the bindings map. + CompositeName path = new CompositeName(name); + + if (path.size() == 0) + { + return this; + } + else + { + String first = path.get(0); + Object obj = bindings.get(first); + if (obj == null) + { + throw new NameNotFoundException(name); + } + else if ((obj instanceof Context) && (path.size() > 1)) + { + Context subContext = (Context) obj; + obj = subContext.lookup(path.getSuffix(1)); + } + + return obj; + } + } + } + + if (result instanceof LinkRef) + { + LinkRef ref = (LinkRef) result; + result = lookup(ref.getLinkName()); + } + + if (result instanceof Reference) + { + try + { + result = NamingManager.getObjectInstance(result, null, null, this.environment); + } + catch (NamingException e) + { + throw e; + } + catch (Exception e) + { + throw (NamingException) new NamingException("could not look up : " + name).initCause(e); + } + } + + if (result instanceof ReadOnlyContext) + { + String prefix = getNameInNamespace(); + if (prefix.length() > 0) + { + prefix = prefix + SEPARATOR; + } + + result = new ReadOnlyContext((ReadOnlyContext) result, environment, prefix + name); + } + + return result; + } + + public Object lookup(Name name) throws NamingException + { + return lookup(name.toString()); + } + + public Object lookupLink(String name) throws NamingException + { + return lookup(name); + } + + public Name composeName(Name name, Name prefix) throws NamingException + { + Name result = (Name) prefix.clone(); + result.addAll(name); + + return result; + } + + public String composeName(String name, String prefix) throws NamingException + { + CompositeName result = new CompositeName(prefix); + result.addAll(new CompositeName(name)); + + return result.toString(); + } + + public NamingEnumeration list(String name) throws NamingException + { + Object o = lookup(name); + if (o == this) + { + return new ListEnumeration(); + } + else if (o instanceof Context) + { + return ((Context) o).list(""); + } + else + { + throw new NotContextException(); + } + } + + public NamingEnumeration listBindings(String name) throws NamingException + { + Object o = lookup(name); + if (o == this) + { + return new ListBindingEnumeration(); + } + else if (o instanceof Context) + { + return ((Context) o).listBindings(""); + } + else + { + throw new NotContextException(); + } + } + + public Object lookupLink(Name name) throws NamingException + { + return lookupLink(name.toString()); + } + + public NamingEnumeration list(Name name) throws NamingException + { + return list(name.toString()); + } + + public NamingEnumeration listBindings(Name name) throws NamingException + { + return listBindings(name.toString()); + } + + public void bind(Name name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void bind(String name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void close() throws NamingException + { + // ignore + } + + public Context createSubcontext(Name name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public Context createSubcontext(String name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void destroySubcontext(Name name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void destroySubcontext(String name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public String getNameInNamespace() throws NamingException + { + return nameInNamespace; + } + + public NameParser getNameParser(Name name) throws NamingException + { + return nameParser; + } + + public NameParser getNameParser(String name) throws NamingException + { + return nameParser; + } + + public void rebind(Name name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void rebind(String name, Object obj) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void rename(Name oldName, Name newName) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void rename(String oldName, String newName) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void unbind(Name name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + public void unbind(String name) throws NamingException + { + throw new OperationNotSupportedException(); + } + + private abstract class LocalNamingEnumeration implements NamingEnumeration + { + private Iterator i = bindings.entrySet().iterator(); + + public boolean hasMore() throws NamingException + { + return i.hasNext(); + } + + public boolean hasMoreElements() + { + return i.hasNext(); + } + + protected Map.Entry getNext() + { + return (Map.Entry) i.next(); + } + + public void close() throws NamingException + { } + } + + private class ListEnumeration extends LocalNamingEnumeration + { + public Object next() throws NamingException + { + return nextElement(); + } + + public Object nextElement() + { + Map.Entry entry = getNext(); + + return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName()); + } + } + + private class ListBindingEnumeration extends LocalNamingEnumeration + { + public Object next() throws NamingException + { + return nextElement(); + } + + public Object nextElement() + { + Map.Entry entry = getNext(); + + return new Binding((String) entry.getKey(), entry.getValue()); + } + } +} diff --git a/java/amqp-1-0-client/build.xml b/java/amqp-1-0-client/build.xml new file mode 100644 index 0000000000..173d7540d4 --- /dev/null +++ b/java/amqp-1-0-client/build.xml @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/AcknowledgeMode.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/AcknowledgeMode.java new file mode 100644 index 0000000000..05d176bc35 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/AcknowledgeMode.java @@ -0,0 +1,28 @@ +/* + * + * 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.amqp_1_0.client; + +public enum AcknowledgeMode +{ + AMO, + ALO, + EO +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java new file mode 100644 index 0000000000..3bb26744c4 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java @@ -0,0 +1,43 @@ +/* + * + * 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.amqp_1_0.client; + +import java.lang.reflect.InvocationTargetException; + +public class Command +{ + public static void main(String[] args) throws + ClassNotFoundException, + NoSuchMethodException, + InvocationTargetException, + IllegalAccessException, + InstantiationException + { + String name = args[0]; + String[] cmdArgs = new String[args.length-1]; + System.arraycopy(args,1,cmdArgs,0,args.length-1); + name = "org.apache.qpid.amqp_1_0.client." + String.valueOf(name.charAt(0)).toUpperCase() + name.substring(1).toLowerCase(); + Class clazz = (Class) Class.forName(name); + Util util = clazz.getDeclaredConstructor(String[].class).newInstance((Object)cmdArgs); + util.run(); + + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java new file mode 100644 index 0000000000..e3d56fae09 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java @@ -0,0 +1,481 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.framing.ConnectionHandler; +import org.apache.qpid.amqp_1_0.transport.AMQPTransport; +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; +import org.apache.qpid.amqp_1_0.transport.Container; +import org.apache.qpid.amqp_1_0.transport.StateChangeListener; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.FrameBody; +import org.apache.qpid.amqp_1_0.type.SaslFrameBody; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; + +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.ByteBuffer; +import java.security.Principal; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class Connection +{ + private static final Logger RAW_LOGGER = Logger.getLogger("RAW"); + private static final int MAX_FRAME_SIZE = 65536; + + private String _address; + private ConnectionEndpoint _conn; + private int _sessionCount; + + + public Connection(final String address, + final int port, + final String username, + final String password) throws ConnectionException + { + this(address, port, username, password, MAX_FRAME_SIZE); + } + + public Connection(final String address, + final int port, + final String username, + final String password, String remoteHostname) throws ConnectionException + { + this(address, port, username, password, MAX_FRAME_SIZE,new Container(),remoteHostname); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final int maxFrameSize) throws ConnectionException + { + this(address,port,username,password,maxFrameSize,new Container()); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final Container container) throws ConnectionException + { + this(address,port,username,password,MAX_FRAME_SIZE,container); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final int maxFrameSize, + final Container container) throws ConnectionException + { + this(address,port,username,password,maxFrameSize,container, null); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final int maxFrameSize, + final Container container, + final String remoteHostname) throws ConnectionException + { + this(address,port,username,password,maxFrameSize,container,remoteHostname,false); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final Container container, + final boolean ssl) throws ConnectionException + { + this(address, port, username, password, MAX_FRAME_SIZE,container,null,ssl); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final String remoteHost, + final boolean ssl) throws ConnectionException + { + this(address, port, username, password, MAX_FRAME_SIZE,new Container(),remoteHost,ssl); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final Container container, + final String remoteHost, + final boolean ssl) throws ConnectionException + { + this(address, port, username, password, MAX_FRAME_SIZE,container,remoteHost,ssl); + } + + public Connection(final String address, + final int port, + final String username, + final String password, + final int maxFrameSize, + final Container container, + final String remoteHostname, boolean ssl) throws ConnectionException + { + + _address = address; + + try + { + final Socket s; + if(ssl) + { + s = SSLSocketFactory.getDefault().createSocket(address, port); + } + else + { + s = new Socket(address, port); + } + + + Principal principal = username == null ? null : new Principal() + { + + public String getName() + { + return username; + } + }; + _conn = new ConnectionEndpoint(container, principal, password); + _conn.setDesiredMaxFrameSize(UnsignedInteger.valueOf(maxFrameSize)); + _conn.setRemoteAddress(s.getRemoteSocketAddress()); + _conn.setRemoteHostname(remoteHostname); + + + + ConnectionHandler.FrameOutput out = new ConnectionHandler.FrameOutput(_conn); + + + final OutputStream outputStream = s.getOutputStream(); + + ConnectionHandler.BytesSource src; + + if(_conn.requiresSASL()) + { + ConnectionHandler.FrameOutput saslOut = new ConnectionHandler.FrameOutput(_conn); + + src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(_conn, (byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte)3, + (byte)1, + (byte)0, + (byte)0), + new ConnectionHandler.FrameToBytesSourceAdapter(saslOut,_conn.getDescribedTypeRegistry()), + new ConnectionHandler.HeaderBytesSource(_conn, (byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte)0, + (byte)1, + (byte)0, + (byte)0), + new ConnectionHandler.FrameToBytesSourceAdapter(out,_conn.getDescribedTypeRegistry()) + ); + + _conn.setSaslFrameOutput(saslOut); + } + else + { + src = new ConnectionHandler.SequentialBytesSource(new ConnectionHandler.HeaderBytesSource(_conn,(byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte)0, + (byte)1, + (byte)0, + (byte)0), + new ConnectionHandler.FrameToBytesSourceAdapter(out,_conn.getDescribedTypeRegistry()) + ); + } + + + //ConnectionHandler.OutputHandler outputHandler = new ConnectionHandler.OutputHandler(outputStream, out, _conn.getDescribedTypeRegistry()); + ConnectionHandler.BytesOutputHandler outputHandler = new ConnectionHandler.BytesOutputHandler(outputStream, src, _conn); + Thread outputThread = new Thread(outputHandler); + outputThread.setDaemon(true); + outputThread.start(); + _conn.setFrameOutputHandler(out); + + + + final ConnectionHandler handler = new ConnectionHandler(_conn); + final InputStream inputStream = s.getInputStream(); + + //final AMQPTransport transport = new AMQPTransport(new AMQPFrameTransport(_conn)); + + Thread inputThread = new Thread(new Runnable() + { + + public void run() + { + try + { + doRead(handler, inputStream); +// doRead(transport, inputStream); + } + finally + { + if(_conn.closedForInput() && _conn.closedForOutput()) + { + try + { + s.close(); + } + catch (IOException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + } + }); + + inputThread.setDaemon(true); + inputThread.start(); + +/* + Thread outputThread = new Thread(new Runnable() + { + + private int _lastWrite; + + public void run() + { + try + { +// doRead(handler, inputStream); + final Object lock = new Object(); + transport.setOutputStateChangeListener(new StateChangeListener() + { + + public void onStateChange(final boolean active) + { + synchronized (lock) + { + lock.notifyAll(); + } + } + }); + + synchronized(lock) + { + while(transport.isOpenForOutput()) + { + _lastWrite = 0; + transport.getNextBytes(new BytesProcessor() + { + + public void processBytes(final ByteBuffer buf) + { + _lastWrite = buf.remaining(); + try + { + outputStream.write(buf.array(), + buf.arrayOffset() + buf.position(), + buf.limit() - buf.position()); + } + catch (IOException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + }); + if(_lastWrite == 0 && transport.isOpenForOutput()) + { + try + { + lock.wait(1000); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + } + } + finally + { + if(_conn.closedForInput() && _conn.closedForOutput()) + { + try + { + s.close(); + } + catch (IOException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + } + }); +*/ + + _conn.open(); + + } + catch (IOException e) + { + throw new ConnectionException(e); + } + + + } + + + + private void doRead(final AMQPTransport transport, final InputStream inputStream) + { + byte[] buf = new byte[2<<15]; + ByteBuffer bbuf = ByteBuffer.wrap(buf); + final Object lock = new Object(); + transport.setInputStateChangeListener(new StateChangeListener(){ + + public void onStateChange(final boolean active) + { + synchronized(lock) + { + lock.notifyAll(); + } + } + }); + + try + { + int read; + while((read = inputStream.read(buf)) != -1) + { + bbuf.position(0); + bbuf.limit(read); + + while(bbuf.hasRemaining() && transport.isOpenForInput()) + { + transport.processBytes(bbuf); + } + + + } + } + catch (IOException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + + } + + public Session createSession() + { + Session session = new Session(this,String.valueOf(_sessionCount++)); + return session; + } + + public ConnectionEndpoint getEndpoint() + { + return _conn; + } + + private void doRead(final ConnectionHandler handler, final InputStream inputStream) + { + byte[] buf = new byte[2<<15]; + + + try + { + int read; + boolean done = false; + while(!done && (read = inputStream.read(buf)) != -1) + { + ByteBuffer bbuf = ByteBuffer.wrap(buf, 0, read); + Binary b = new Binary(buf,0,read); + + if(RAW_LOGGER.isLoggable(Level.FINE)) + { + RAW_LOGGER.fine("RECV [" + _conn.getRemoteAddress() + "] : " + b.toString()); + } + /*System.err.println(b); + System.err.println("XXX: " + bbuf.hasRemaining() + "; " + handler.isDone()); + if(handler.isDone()) + { + System.err.println(handler.getClass().getName() + "IS DONE!"); + } */ + while(bbuf.hasRemaining() && !handler.isDone()) + { + handler.parse(bbuf); + } + + + } + } + catch (IOException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + + public void close() + { + _conn.close(); + + synchronized (_conn.getLock()) + { + while(!_conn.closedForInput()) + { + try + { + _conn.getLock().wait(); + } + catch (InterruptedException e) + { + + } + } + } + } + + + public static class ConnectionException extends Exception + { + public ConnectionException(Throwable cause) + { + super(cause); + } + } + + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java new file mode 100644 index 0000000000..b58ce6bfe5 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java @@ -0,0 +1,407 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; +import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Demo extends Util +{ + private static final String USAGE_STRING = "demo [options] [ ...]\n\nOptions:"; + private static final String OPCODE = "opcode"; + private static final String ACTION = "action"; + private static final String MESSAGE_ID = "message-id"; + private static final String VENDOR = "vendor"; + private static final String LOG = "log"; + private static final String RECEIVED = "received"; + private static final String TEST = "test"; + private static final String APACHE = "apache"; + private static final String SENT = "sent"; + private static final String LINK_REF = "link-ref"; + private static final String HOST = "host"; + private static final String PORT = "port"; + private static final String SASL_USER = "sasl-user"; + private static final String SASL_PASSWORD = "sasl-password"; + private static final String ROLE = "role"; + private static final String ADDRESS = "address"; + private static final String SENDER = "sender"; + private static final String SEND_MESSAGE = "send-message"; + private static final String ANNOUNCE = "announce"; + private static final String MESSAGE_VENDOR = "message-vendor"; + private static final String CREATE_LINK = "create-link"; + + public static void main(String[] args) + { + new Demo(args).run(); + } + + public Demo(String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return false; + } + + @Override + protected boolean hasLinkNameOption() + { + return false; + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; + } + + @Override + protected boolean hasSizeOption() + { + return false; + } + + @Override + protected boolean hasBlockOption() + { + return false; + } + + @Override + protected boolean hasStdInOption() + { + return false; + } + + @Override + protected boolean hasTxnOption() + { + return false; + } + + @Override + protected boolean hasModeOption() + { + return true; + } + + @Override + protected boolean hasCountOption() + { + return false; + } + + @Override + protected boolean hasWindowSizeOption() + { + return false; + } + + public void run() + { + + try + { + + final String vendor = getArgs()[0]; + final String queue = "control"; + + String message = ""; + + Connection conn = newConnection(); + Session session = conn.createSession(); + + + Receiver responseReceiver; + + responseReceiver = session.createTemporaryQueueReceiver(); + + + + + responseReceiver.setCredit(UnsignedInteger.valueOf(getWindowSize()), true); + + + + Sender s = session.createSender(queue, getWindowSize(), getMode()); + + + Properties properties = new Properties(); + properties.setMessageId(java.util.UUID.randomUUID()); + properties.setReplyTo(responseReceiver.getAddress()); + + HashMap appPropMap = new HashMap(); + ApplicationProperties appProperties = new ApplicationProperties(appPropMap); + + appPropMap.put(OPCODE, ANNOUNCE); + appPropMap.put(VENDOR, vendor); + appPropMap.put(ADDRESS,responseReceiver.getAddress()); + + AmqpValue amqpValue = new AmqpValue(message); + Section[] sections = { properties, appProperties, amqpValue}; + final Message message1 = new Message(Arrays.asList(sections)); + + s.send(message1); + + Map sendingLinks = new HashMap(); + Map receivingLinks = new HashMap(); + + + boolean done = false; + + while(!done) + { + boolean wait = true; + Message m = responseReceiver.receive(false); + if(m != null) + { + List
payload = m.getPayload(); + wait = false; + ApplicationProperties props = m.getApplicationProperties(); + Map map = props.getValue(); + String op = (String) map.get(OPCODE); + if("reset".equals(op)) + { + for(Sender sender : sendingLinks.values()) + { + try + { + sender.close(); + Session session1 = sender.getSession(); + session1.close(); + session1.getConnection().close(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + for(Receiver receiver : receivingLinks.values()) + { + try + { + receiver.close(); + receiver.getSession().close(); + receiver.getSession().getConnection().close(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + sendingLinks.clear(); + receivingLinks.clear(); + } + else if(CREATE_LINK.equals(op)) + { + Object linkRef = map.get(LINK_REF); + String host = (String) map.get(HOST); + Object o = map.get(PORT); + int port = Integer.parseInt(String.valueOf(o)); + String user = (String) map.get(SASL_USER); + String password = (String) map.get(SASL_PASSWORD); + String role = (String) map.get(ROLE); + String address = (String) map.get(ADDRESS); + System.err.println("Host: " + host + "\tPort: " + port + "\t user: " + user +"\t password: " + password); + try{ + + + Connection conn2 = new Connection(host, port, user, password, host); + Session session2 = conn2.createSession(); + if(sendingLinks.containsKey(linkRef)) + { + try + { + sendingLinks.remove(linkRef).close(); + } + catch (Exception e) + { + + } + } + if(receivingLinks.containsKey(linkRef)) + { + try + { + receivingLinks.remove(linkRef).close(); + } + catch (Exception e) + { + + } + } + if(SENDER.equals(role)) + { + + System.err.println("%%% Creating sender (" + linkRef + ")"); + Sender sender = session2.createSender(address); + sendingLinks.put(linkRef, sender); + } + else + { + + System.err.println("%%% Creating receiver (" + linkRef + ")"); + Receiver receiver2 = session2.createReceiver(address); + receiver2.setCredit(UnsignedInteger.valueOf(getWindowSize()), true); + + receivingLinks.put(linkRef, receiver2); + } + } + catch(Exception e) + { + e.printStackTrace(); + } + } + else if(SEND_MESSAGE.equals(op)) + { + Sender sender = sendingLinks.get(map.get(LINK_REF)); + Properties m2props = new Properties(); + Object messageId = map.get(MESSAGE_ID); + m2props.setMessageId(messageId); + Map m2propmap = new HashMap(); + m2propmap.put(OPCODE, TEST); + m2propmap.put(VENDOR, vendor); + ApplicationProperties m2appProps = new ApplicationProperties(m2propmap); + Message m2 = new Message(Arrays.asList(m2props, m2appProps, new AmqpValue("AMQP-"+messageId))); + sender.send(m2); + + Map m3propmap = new HashMap(); + m3propmap.put(OPCODE, LOG); + m3propmap.put(ACTION, SENT); + m3propmap.put(MESSAGE_ID, messageId); + m3propmap.put(VENDOR, vendor); + m3propmap.put(MESSAGE_VENDOR, vendor); + + + Message m3 = new Message(Arrays.asList(new ApplicationProperties(m3propmap), + new AmqpValue("AMQP-"+messageId))); + s.send(m3); + + } + + responseReceiver.acknowledge(m); + } + else + { + for(Map.Entry entry : receivingLinks.entrySet()) + { + m = entry.getValue().receive(false); + if(m != null) + { + wait = false; + + System.err.println("%%% Received message from " + entry.getKey()); + + Properties mp = m.getProperties(); + ApplicationProperties ap = m.getApplicationProperties(); + + Map m3propmap = new HashMap(); + m3propmap.put(OPCODE, LOG); + m3propmap.put(ACTION, RECEIVED); + m3propmap.put(MESSAGE_ID, mp.getMessageId()); + m3propmap.put(VENDOR, vendor); + m3propmap.put(MESSAGE_VENDOR, ap.getValue().get(VENDOR)); + + Message m3 = new Message(Arrays.asList(new ApplicationProperties(m3propmap), + new AmqpValue("AMQP-"+mp.getMessageId()))); + s.send(m3); + + entry.getValue().acknowledge(m); + } + + } + } + + if(wait) + { + try + { + Thread.sleep(500l); + } + catch (InterruptedException e) + { + e.printStackTrace(); //TODO. + } + } + + } + + + + + + + + + + s.close(); + session.close(); + conn.close(); + + } + catch (Connection.ConnectionException e) + { + e.printStackTrace(); //TODO. + } + catch (Sender.SenderClosingException e) + { + e.printStackTrace(); //TODO. + } + catch (Sender.SenderCreationException e) + { + e.printStackTrace(); //TODO. + } + catch (AmqpErrorException e) + { + e.printStackTrace(); //TODO. + } + + } + + protected boolean hasSingleLinkPerConnectionMode() + { + return false; + } + + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + } + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java new file mode 100644 index 0000000000..f61fd64a61 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java @@ -0,0 +1,116 @@ +package org.apache.qpid.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.commons.cli.Options; + +public class Dump extends Util +{ + private static final String USAGE_STRING = "dump [options]
\n\nOptions:"; + + + protected Dump(String[] args) + { + super(args); + } + + public static void main(String[] args) + { + new Dump(args).run(); + } + + @Override + protected boolean hasLinkDurableOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasLinkNameOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasSizeOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasBlockOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasStdInOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasTxnOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasModeOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected boolean hasCountOption() + { + return false; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected void printUsage(Options options) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + protected void run() + { + final String queue = getArgs()[0]; + + try + { + Connection conn = newConnection(); + + Session session = conn.createSession(); + + + Sender s = session.createSender(queue, 10); + + Message message = new Message("dump me"); + message.setDeliveryTag(new Binary("dump".getBytes())); + + s.send(message); + + s.close(); + session.close(); + conn.close(); + + } catch (Connection.ConnectionException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + catch (Sender.SenderCreationException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (Sender.SenderClosingException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java new file mode 100644 index 0000000000..43ddd6ca25 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java @@ -0,0 +1,327 @@ +package org.apache.qpid.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; + +import java.io.*; +import java.nio.ByteBuffer; +import java.util.*; + +public class Filereceiver extends Util +{ + private static final String USAGE_STRING = "filereceiver [options]
\n\nOptions:"; + + protected Filereceiver(String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return true; + } + + @Override + protected boolean hasLinkNameOption() + { + return true; + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; + } + + @Override + protected boolean hasSizeOption() + { + return false; + } + + @Override + protected boolean hasBlockOption() + { + return true; + } + + @Override + protected boolean hasStdInOption() + { + return false; + } + + @Override + protected boolean hasTxnOption() + { + return false; + } + + @Override + protected boolean hasModeOption() + { + return false; + } + + @Override + protected boolean hasCountOption() + { + return false; + } + + @Override + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + + } + + @Override + protected void run() + { + final String queue = getArgs()[0]; + final String directoryName = getArgs()[1]; + + try + { + Connection conn = newConnection(); + + Session session = conn.createSession(); + + final File directory = new File(directoryName); + if(directory.isDirectory() && directory.canWrite()) + { + File tmpDirectory = new File(directoryName, ".tmp"); + if(!tmpDirectory.exists()) + { + tmpDirectory.mkdir(); + } + + String[] unsettledFiles = tmpDirectory.list(); + + Map unsettled = new HashMap(); + final Map unsettledFileNames = new HashMap(); + + Accepted accepted = new Accepted(); + + for(String fileName : unsettledFiles) + { + File theFile = new File(tmpDirectory, fileName); + if(theFile.isFile()) + { + if(fileName.startsWith("~") && fileName.endsWith("~")) + { + theFile.delete(); + } + else + { + int splitPoint = fileName.indexOf("."); + String deliveryTagStr = fileName.substring(0,splitPoint); + String actualFileName = fileName.substring(splitPoint+1); + + byte[] bytes = new byte[deliveryTagStr.length()/2]; + + + for(int i = 0; i < bytes.length; i++) + { + char c = deliveryTagStr.charAt(2*i); + char d = deliveryTagStr.charAt(1+(2*i)); + + bytes[i] = (byte) (((c <= '9' ? c - '0' : c - 'W') << 4) + | (d <= '9' ? d - '0' : d - 'W')); + + } + Binary deliveryTag = new Binary(bytes); + unsettled.put(deliveryTag, accepted); + unsettledFileNames.put(deliveryTag, fileName); + } + } + + } + + Receiver r = session.createReceiver(queue, AcknowledgeMode.EO, getLinkName(), isDurableLink(), + unsettled); + + Map remoteUnsettled = r.getRemoteUnsettled(); + + for(Map.Entry entry : unsettledFileNames.entrySet()) + { + if(remoteUnsettled == null || !remoteUnsettled.containsKey(entry.getKey())) + { + + File tmpFile = new File(tmpDirectory, entry.getValue()); + final File dest = new File(directory, + entry.getValue().substring(entry.getValue().indexOf(".") + 1)); + if(dest.exists()) + { + System.err.println("Duplicate detected - filename " + dest.getName()); + } + + tmpFile.renameTo(dest); + } + } + + + int credit = 10; + + r.setCredit(UnsignedInteger.valueOf(credit), true); + + + int received = 0; + Message m = null; + do + { + m = isBlock() && received == 0 ? r.receive() : r.receive(10000); + if(m != null) + { + if(m.isResume() && unsettled.containsKey(m.getDeliveryTag())) + { + final String tmpFileName = unsettledFileNames.get(m.getDeliveryTag()); + final File unsettledFile = new File(tmpDirectory, + tmpFileName); + r.acknowledge(m, new Receiver.SettledAction() + { + public void onSettled(final Binary deliveryTag) + { + int splitPoint = tmpFileName.indexOf("."); + + String fileName = tmpFileName.substring(splitPoint+1); + + final File dest = new File(directory, fileName); + if(dest.exists()) + { + System.err.println("Duplicate detected - filename " + dest.getName()); + } + unsettledFile.renameTo(dest); + unsettledFileNames.remove(deliveryTag); + } + }); + } + else + { + received++; + List
sections = m.getPayload(); + Binary deliveryTag = m.getDeliveryTag(); + StringBuilder tagNameBuilder = new StringBuilder(); + + ByteBuffer dtbuf = deliveryTag.asByteBuffer(); + while(dtbuf.hasRemaining()) + { + tagNameBuilder.append(String.format("%02x", dtbuf.get())); + } + + + ApplicationProperties properties = null; + List data = new ArrayList(); + int totalSize = 0; + for(Section section : sections) + { + if(section instanceof ApplicationProperties) + { + properties = (ApplicationProperties) section; + } + else if(section instanceof AmqpValue) + { + AmqpValue value = (AmqpValue) section; + if(value.getValue() instanceof Binary) + { + Binary binary = (Binary) value.getValue(); + data.add(binary); + totalSize += binary.getLength(); + + } + else + { + // TODO exception + } + } + else if(section instanceof Data) + { + Data value = (Data) section; + Binary binary = value.getValue(); + data.add(binary); + totalSize += binary.getLength(); + + } + } + if(properties != null) + { + final String fileName = (String) properties.getValue().get("filename"); + byte[] fileData = new byte[totalSize]; + ByteBuffer buf = ByteBuffer.wrap(fileData); + int offset = 0; + for(Binary bin : data) + { + buf.put(bin.asByteBuffer()); + } + File outputFile = new File(tmpDirectory, "~"+fileName+"~"); + if(outputFile.exists()) + { + outputFile.delete(); + } + FileOutputStream fos = new FileOutputStream(outputFile); + fos.write(fileData); + fos.flush(); + fos.close(); + + final File unsettledFile = new File(tmpDirectory, tagNameBuilder.toString() + "." + + fileName); + outputFile.renameTo(unsettledFile); + r.acknowledge(m, new Receiver.SettledAction() + { + public void onSettled(final Binary deliveryTag) + { + final File dest = new File(directory, fileName); + if(dest.exists()) + { + System.err.println("Duplicate detected - filename " + dest.getName()); + } + unsettledFile.renameTo(dest); + + } + }); + + } + } + } + } + while(m != null); + + + r.close(); + } + else + { + System.err.println("No such directory: " + directoryName); + } + session.close(); + conn.close(); + } + catch (Connection.ConnectionException e) + { + e.printStackTrace(); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); //TODO. + } + catch (IOException e) + { + e.printStackTrace(); //TODO. + } + catch (AmqpErrorException e) + { + e.printStackTrace(); //TODO. + } + + } + + public static void main(String[] args) + { + new Filereceiver(args).run(); + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java new file mode 100644 index 0000000000..83b305ac03 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java @@ -0,0 +1,276 @@ +package org.apache.qpid.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.DeliveryState; +import org.apache.qpid.amqp_1_0.type.Outcome; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.*; + +public class Filesender extends Util +{ + private static final String USAGE_STRING = "filesender [options]
\n\nOptions:"; + + protected Filesender(String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return true; + } + + @Override + protected boolean hasLinkNameOption() + { + return true; + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; + } + + @Override + protected boolean hasSizeOption() + { + return false; + } + + @Override + protected boolean hasBlockOption() + { + return false; + } + + @Override + protected boolean hasStdInOption() + { + return false; + } + + @Override + protected boolean hasTxnOption() + { + return false; + } + + @Override + protected boolean hasModeOption() + { + return false; + } + + @Override + protected boolean hasCountOption() + { + return false; + } + + @Override + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + + } + + @Override + protected void run() + { + final String queue = getArgs()[0]; + final String directoryName = getArgs()[1]; + + try + { + MessageDigest md5 = MessageDigest.getInstance("MD5"); + Connection conn = newConnection(); + + Session session = conn.createSession(); + + File directory = new File(directoryName); + if(directory.isDirectory() && directory.canWrite()) + { + + File tmpDirectory = new File(directoryName, ".tmp"); + if(!tmpDirectory.exists()) + { + tmpDirectory.mkdir(); + } + + String[] unsettledFiles = tmpDirectory.list(); + + + + Map unsettled = new HashMap(); + Map unsettledFileNames = new HashMap(); + for(String fileName : unsettledFiles) + { + File aFile = new File(tmpDirectory, fileName); + if(aFile.canRead() && aFile.canWrite()) + { + Binary deliveryTag = new Binary(md5.digest(fileName.getBytes())); + unsettled.put(deliveryTag, null); + unsettledFileNames.put(deliveryTag, fileName); + } + } + + + Sender s = session.createSender(queue, 10, AcknowledgeMode.EO, getLinkName(), isDurableLink(), + unsettled); + + Map remoteUnsettled = s.getRemoteUnsettled(); + + for(Map.Entry entry: unsettledFileNames.entrySet()) + { + if(remoteUnsettled == null || !remoteUnsettled.containsKey(entry.getKey())) + { + (new File(tmpDirectory, entry.getValue())).renameTo(new File(directory, entry.getValue())); + } + } + + if(remoteUnsettled != null) + { + for(Map.Entry entry : remoteUnsettled.entrySet()) + { + if(entry.getValue() instanceof Accepted) + { + final String fileName = unsettledFileNames.get(entry.getKey()); + if(fileName != null) + { + + Message resumed = new Message(); + resumed.setDeliveryTag(entry.getKey()); + resumed.setDeliveryState(entry.getValue()); + resumed.setResume(Boolean.TRUE); + resumed.setSettled(Boolean.TRUE); + + + + final File unsettledFile = new File(tmpDirectory, fileName); + unsettledFile.delete(); + + s.send(resumed); + + } + + } + else if(entry.getValue() instanceof Received || entry.getValue() == null) + { + final File unsettledFile = new File(tmpDirectory, unsettledFileNames.get(entry.getKey())); + Message resumed = createMessageFromFile(md5, unsettledFileNames.get(entry.getKey()), unsettledFile); + resumed.setResume(Boolean.TRUE); + Sender.OutcomeAction action = new Sender.OutcomeAction() + { + public void onOutcome(Binary deliveryTag, Outcome outcome) + { + if(outcome instanceof Accepted) + { + unsettledFile.delete(); + } + } + }; + s.send(resumed, action); + + } + } + } + + + + String[] files = directory.list(); + + for(String fileName : files) + { + final File file = new File(directory, fileName); + + if(file.canRead() && file.canWrite() && !file.isDirectory()) + { + Message message = createMessageFromFile(md5, fileName, file); + + final File unsettledFile = new File(tmpDirectory, fileName); + + Sender.OutcomeAction action = new Sender.OutcomeAction() + { + public void onOutcome(Binary deliveryTag, Outcome outcome) + { + if(outcome instanceof Accepted) + { + unsettledFile.delete(); + } + } + }; + + file.renameTo(unsettledFile); + + s.send(message, action); + } + } + + s.close(); + } + else + { + System.err.println("No such directory: " + directory); + } + session.close(); + conn.close(); + } + catch (Connection.ConnectionException e) + { + e.printStackTrace(); + } + catch (Sender.SenderCreationException e) + { + e.printStackTrace(); + } catch (FileNotFoundException e) + { + e.printStackTrace(); + } catch (IOException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (NoSuchAlgorithmException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (Sender.SenderClosingException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + + } + + private Message createMessageFromFile(MessageDigest md5, String fileName, File file) throws IOException + { + FileInputStream fis = new FileInputStream(file); + byte[] data = new byte[(int) file.length()]; + + int read = fis.read(data); + + fis.close(); + + Section applicationProperties = new ApplicationProperties(Collections.singletonMap("filename", fileName)); + Section amqpValue = new Data(new Binary(data)); + Message message = new Message(Arrays.asList(applicationProperties, amqpValue)); + Binary deliveryTag = new Binary(md5.digest(fileName.getBytes())); + message.setDeliveryTag(deliveryTag); + md5.reset(); + return message; + } + + public static void main(String[] args) + { + new Filesender(args).run(); + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Message.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Message.java new file mode 100644 index 0000000000..7c1172898b --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Message.java @@ -0,0 +1,148 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.DeliveryState; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; +import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class Message +{ + private Binary _deliveryTag; + private List
_payload = new ArrayList
(); + private Boolean _resume; + private boolean _settled; + private DeliveryState _deliveryState; + private Receiver _receiver; + + + public Message() + { + } + + public Message(Collection
sections) + { + _payload.addAll(sections); + } + + public Message(Section section) + { + this(Collections.singletonList(section)); + } + + public Message(String message) + { + this(new AmqpValue(message)); + } + + + public Binary getDeliveryTag() + { + return _deliveryTag; + } + + public void setDeliveryTag(Binary deliveryTag) + { + _deliveryTag = deliveryTag; + } + + public List
getPayload() + { + return Collections.unmodifiableList(_payload); + } + + private T getSection(Class clazz) + { + for(Section s : _payload) + { + if(clazz.isAssignableFrom(s.getClass())) + { + return (T) s; + } + } + return null; + } + + public ApplicationProperties getApplicationProperties() + { + return getSection(ApplicationProperties.class); + } + + public Properties getProperties() + { + return getSection(Properties.class); + } + + public Header getHeader() + { + return getSection(Header.class); + } + + + public void setResume(final Boolean resume) + { + _resume = resume; + } + + public boolean isResume() + { + return Boolean.TRUE.equals(_resume); + } + + public void setDeliveryState(DeliveryState state) + { + _deliveryState = state; + } + + public DeliveryState getDeliveryState() + { + return _deliveryState; + } + + public void setSettled(boolean settled) + { + _settled = settled; + } + + public boolean getSettled() + { + return _settled; + } + + public void setReceiver(final Receiver receiver) + { + _receiver = receiver; + } + + public Receiver getReceiver() + { + return _receiver; + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java new file mode 100644 index 0000000000..07ae54b54f --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java @@ -0,0 +1,77 @@ +/* + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.codec.ValueHandler; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +public class ReadBytes +{ + + public static void main(String[] args) throws IOException, AmqpErrorException + { + + if(args.length == 0) + { + readBytes(System.in); + } + else + { + for(String fileName : args) + { + System.out.println("=========================== " + fileName + " ==========================="); + final FileInputStream fis = new FileInputStream(fileName); + readBytes(fis); + fis.close(); + } + } + + } + + private static void readBytes(final InputStream inputStream) throws IOException, AmqpErrorException + { + byte[] bytes = new byte[4096]; + + ValueHandler valueHandler = new ValueHandler(AMQPDescribedTypeRegistry.newInstance()); + + int count; + + while((count = inputStream.read(bytes))!=-1) + { + ByteBuffer buf = ByteBuffer.wrap(bytes); + buf.limit(count); + while(buf.hasRemaining()) + { + + final Object value = valueHandler.parse(buf); + System.out.print((value == null ? "" : value.getClass().getName() + ":") +value +"\n"); + + } + } + + } + + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java new file mode 100644 index 0000000000..0da9dc3fb7 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java @@ -0,0 +1,246 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.commons.cli.*; +import org.apache.qpid.amqp_1_0.type.messaging.ExactSubjectFilter; +import org.apache.qpid.amqp_1_0.type.messaging.Filter; +import org.apache.qpid.amqp_1_0.type.messaging.MatchingSubjectFilter; + +import java.util.Collections; + +public class Receive extends Util +{ + private static final String USAGE_STRING = "receive [options]
\n\nOptions:"; + private static final UnsignedLong UNSIGNED_LONG_ONE = UnsignedLong.valueOf(1L); + private UnsignedLong _lastCorrelationId; + + public static void main(String[] args) + { + new Receive(args).run(); + } + + + public Receive(final String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return true; + } + + @Override + protected boolean hasLinkNameOption() + { + return true; + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; + } + + @Override + protected boolean hasSizeOption() + { + return false; + } + + @Override + protected boolean hasBlockOption() + { + return true; + } + + @Override + protected boolean hasStdInOption() + { + return true; + } + + @Override + protected boolean hasTxnOption() + { + return true; + } + + @Override + protected boolean hasModeOption() + { + return true; + } + + @Override + protected boolean hasCountOption() + { + return true; + } + + @Override + protected boolean hasWindowSizeOption() + { + return true; + } + + @Override + protected boolean hasFilterOption() + { + return true; + } + + protected void run() + { + + try + { + final String queue = getArgs()[0]; + + String message = ""; + + Connection conn = newConnection(); + + + Session session = conn.createSession(); + + Filter filter = null; + if(getFilter() != null) + { + String[] filterParts = getFilter().split("=",2); + if("exact-subject".equals(filterParts[0])) + { + filter = new ExactSubjectFilter(filterParts[1]); + } + else if("matching-subject".equals(filterParts[0])) + { + filter = new MatchingSubjectFilter(filterParts[1]); + } + else + { + System.err.println("Unknown filter type: " + filterParts[0]); + } + } + + Receiver r = + filter == null + ? session.createReceiver(queue, getMode(), getLinkName(), isDurableLink()) + : session.createReceiver(queue, getMode(), getLinkName(), isDurableLink(), Collections.singletonMap(Symbol.valueOf("filter"), filter), null); + Transaction txn = null; + + int credit = 0; + int receivedCount = 0; + + if(!useStdIn()) + { + if(getArgs().length <= 2) + { + + Transaction txn2 = null; + if(useTran()) + { + txn = session.createSessionLocalTransaction(); + txn2 = session.createSessionLocalTransaction(); + } + + for(int i = 0; i < getCount(); i++) + { + + if(credit == 0) + { + if(getCount() - i <= getWindowSize()) + { + credit = getCount() - i; + + } + else + { + credit = getWindowSize(); + + } + + { + r.setCredit(UnsignedInteger.valueOf(credit), false); + } + if(!isBlock()) + r.drain(); + } + + Message m = isBlock() ? r.receive() : r.receive(1000L); + credit--; + if(m==null) + { + break; + } + + + + r.acknowledge(m.getDeliveryTag(),txn); + + receivedCount++; + + System.out.println("Received Message : " + m.getPayload()); + } + + if(useTran()) + { + txn.commit(); + } + } + else + { + // TODO + } + } + else + { + // TODO + } + r.close(); + session.close(); + conn.close(); + System.out.println("Total Messages Received: " + receivedCount); + } + catch (Connection.ConnectionException e) + { + e.printStackTrace(); //TODO. + } + catch (AmqpErrorException e) + { + e.printStackTrace(); //TODO. + } + + } + + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + } + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java new file mode 100644 index 0000000000..ad390fd498 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java @@ -0,0 +1,561 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.messaging.SectionDecoder; +import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler; +import org.apache.qpid.amqp_1_0.transport.LinkEndpoint; +import org.apache.qpid.amqp_1_0.transport.ReceivingLinkEndpoint; +import org.apache.qpid.amqp_1_0.transport.ReceivingLinkListener; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.DeliveryState; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Source; +import org.apache.qpid.amqp_1_0.type.messaging.Target; +import org.apache.qpid.amqp_1_0.type.transaction.TransactionalState; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; + +public class Receiver implements DeliveryStateHandler +{ + private ReceivingLinkEndpoint _endpoint; + private int _id; + private static final UnsignedInteger DEFAULT_INITIAL_CREDIT = UnsignedInteger.valueOf(100); + private Session _session; + + private Queue _prefetchQueue = new ConcurrentLinkedQueue(); + private Map _unsettledMap = new HashMap(); + private MessageArrivalListener _messageArrivalListener; + private org.apache.qpid.amqp_1_0.type.transport.Error _error; + + public Receiver(final Session session, + final String linkName, + final Target target, + final Source source, + final AcknowledgeMode ackMode) throws AmqpErrorException + { + this(session, linkName, target, source, ackMode, false); + } + + public Receiver(final Session session, + final String linkName, + final Target target, + final Source source, + final AcknowledgeMode ackMode, + boolean isDurable) throws AmqpErrorException + { + this(session,linkName,target,source,ackMode,isDurable,null); + } + + public Receiver(final Session session, + final String linkName, + final Target target, + final Source source, + final AcknowledgeMode ackMode, + final boolean isDurable, + final Map unsettled) throws AmqpErrorException + { + + _session = session; + if(isDurable) + { + source.setDurable(TerminusDurability.UNSETTLED_STATE); + source.setExpiryPolicy(TerminusExpiryPolicy.NEVER); + } + else if(source != null) + { + source.setDurable(TerminusDurability.NONE); + source.setExpiryPolicy(TerminusExpiryPolicy.LINK_DETACH); + } + _endpoint = session.getEndpoint().createReceivingLinkEndpoint(linkName, target, source, + UnsignedInteger.ZERO); + + _endpoint.setDeliveryStateHandler(this); + + switch(ackMode) + { + case ALO: + _endpoint.setSendingSettlementMode(SenderSettleMode.UNSETTLED); + _endpoint.setReceivingSettlementMode(ReceiverSettleMode.FIRST); + break; + case AMO: + _endpoint.setSendingSettlementMode(SenderSettleMode.SETTLED); + _endpoint.setReceivingSettlementMode(ReceiverSettleMode.FIRST); + break; + case EO: + _endpoint.setSendingSettlementMode(SenderSettleMode.UNSETTLED); + _endpoint.setReceivingSettlementMode(ReceiverSettleMode.SECOND); + break; + + } + + _endpoint.setLinkEventListener(new ReceivingLinkListener.DefaultLinkEventListener() + { + @Override public void messageTransfer(final Transfer xfr) + { + _prefetchQueue.add(xfr); + postPrefetchAction(); + } + + @Override + public void remoteDetached(final LinkEndpoint endpoint, final Detach detach) + { + _error = detach.getError(); + super.remoteDetached(endpoint, detach); + } + }); + + _endpoint.setLocalUnsettled(unsettled); + _endpoint.attach(); + + synchronized(_endpoint.getLock()) + { + while(!_endpoint.isAttached() && !_endpoint.isDetached()) + { + try + { + _endpoint.getLock().wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + + if(_endpoint.getSource() == null) + { + synchronized(_endpoint.getLock()) + { + while(!_endpoint.isDetached()) + { + try + { + _endpoint.getLock().wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + throw new AmqpErrorException(getError()); + } + else + { + + } + } + + private void postPrefetchAction() + { + if(_messageArrivalListener != null) + { + _messageArrivalListener.messageArrived(this); + } + } + + public void setCredit(UnsignedInteger credit, boolean window) + { + _endpoint.setLinkCredit(credit); + _endpoint.setCreditWindow(window); + + } + + + public String getAddress() + { + return ((Source)_endpoint.getSource()).getAddress(); + } + + public Map getFilter() + { + return ((Source)_endpoint.getSource()).getFilter(); + } + + public Message receive() + { + return receive(-1L); + } + + public Message receive(boolean wait) + { + return receive(wait ? -1L : 0L); + } + + // 0 means no wait, -1 wait forever + public Message receive(long wait) + { + Message m = null; + Transfer xfr; + long endTime = wait > 0L ? System.currentTimeMillis() + wait : 0L; + + while((xfr = receiveFromPrefetch(wait)) != null ) + { + + if(!Boolean.TRUE.equals(xfr.getAborted())) + { + Binary deliveryTag = xfr.getDeliveryTag(); + Boolean resume = xfr.getResume(); + + List
sections = new ArrayList
(); + List payloads = new ArrayList(); + int totalSize = 0; + + boolean hasMore; + do + { + hasMore = Boolean.TRUE.equals(xfr.getMore()); + + ByteBuffer buf = xfr.getPayload(); + + if(buf != null) + { + + totalSize += buf.remaining(); + + payloads.add(buf); + } + if(hasMore) + { + xfr = receiveFromPrefetch(0L); + if(xfr== null) + { + // TODO - this is wrong!!!! + System.out.println("eeek"); + } + } + } + while(hasMore && !Boolean.TRUE.equals(xfr.getAborted())); + + if(!Boolean.TRUE.equals(xfr.getAborted())) + { + ByteBuffer allPayload = ByteBuffer.allocate(totalSize); + for(ByteBuffer payload : payloads) + { + allPayload.put(payload); + } + allPayload.flip(); + SectionDecoder decoder = _session.getSectionDecoder(); + + try + { + sections = decoder.parseAll(allPayload); + } + catch (AmqpErrorException e) + { + // todo - throw a sensible error + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + m = new Message(sections); + m.setDeliveryTag(deliveryTag); + m.setResume(resume); + m.setReceiver(this); + break; + } + } + + if(wait > 0L) + { + wait = endTime - System.currentTimeMillis(); + if(wait <=0L) + { + break; + } + } + } + + + return m; + + } + + private Transfer receiveFromPrefetch(long wait) + { + long endTime = ((wait >0L) ? (System.currentTimeMillis() + wait) : 0L); + final Object lock = _endpoint.getLock(); + synchronized(lock) + { + Transfer xfr; + while(((xfr = _prefetchQueue.peek()) == null) && !_endpoint.isDrained() && !_endpoint.isDetached() + && wait != 0) + { + try + { + if(wait>0L) + { + lock.wait(wait); + } + else if(wait<0L) + { + lock.wait(); + } + } + catch (InterruptedException e) + { + return null; + } + if(wait > 0L) + { + wait = endTime - System.currentTimeMillis(); + if(wait <= 0L) + { + break; + } + } + + } + if(xfr != null) + { + _prefetchQueue.poll(); + + } + + return xfr; + } + + } + + + public void release(final Message m) + { + release(m.getDeliveryTag()); + } + + public void release(Binary deliveryTag) + { + update(new Released(), deliveryTag, null, null); + } + + + public void modified(Binary tag) + { + final Modified outcome = new Modified(); + outcome.setDeliveryFailed(true); + + update(outcome, tag, null, null); + } + + public void acknowledge(final Message m) + { + acknowledge(m.getDeliveryTag()); + } + + public void acknowledge(final Message m, SettledAction a) + { + acknowledge(m.getDeliveryTag(), a); + } + + + public void acknowledge(final Message m, Transaction txn) + { + acknowledge(m.getDeliveryTag(), txn); + } + + + public void acknowledge(final Binary deliveryTag) + { + acknowledge(deliveryTag, null, null); + } + + + public void acknowledge(final Binary deliveryTag, SettledAction a) + { + acknowledge(deliveryTag, null, a); + } + + public void acknowledge(final Binary deliveryTag, final Transaction txn) + { + acknowledge(deliveryTag, txn, null); + } + + public void acknowledge(final Binary deliveryTag, final Transaction txn, SettledAction action) + { + update(new Accepted(), deliveryTag, txn, action); + } + + public void update(Outcome outcome, final Binary deliveryTag, final Transaction txn, SettledAction action) + { + + DeliveryState state; + if(txn != null) + { + TransactionalState txnState = new TransactionalState(); + txnState.setOutcome(outcome); + txnState.setTxnId(txn.getTxnId()); + state = txnState; + } + else + { + state = (DeliveryState) outcome; + } + boolean settled = txn == null && !ReceiverSettleMode.SECOND.equals(_endpoint.getReceivingSettlementMode()); + + if(!(settled || action == null)) + { + _unsettledMap.put(deliveryTag, action); + } + + _endpoint.updateDisposition(deliveryTag,state, settled); + } + + public Error getError() + { + return _error; + } + + public void acknowledgeAll(Message m) + { + acknowledgeAll(m.getDeliveryTag()); + } + + public void acknowledgeAll(Binary deliveryTag) + { + acknowledgeAll(deliveryTag, null, null); + } + + public void acknowledgeAll(Binary deliveryTag, final Transaction txn, SettledAction action) + { + updateAll(new Accepted(), deliveryTag, txn, action); + } + + public void updateAll(Outcome outcome, Binary deliveryTag) + { + updateAll(outcome, deliveryTag, null, null); + } + + public void updateAll(Outcome outcome, Binary deliveryTag, final Transaction txn, SettledAction action) + { + DeliveryState state; + + if(txn != null) + { + TransactionalState txnState = new TransactionalState(); + txnState.setOutcome(outcome); + txnState.setTxnId(txn.getTxnId()); + state = txnState; + } + else + { + state = (DeliveryState) outcome; + } + boolean settled = txn == null && !ReceiverSettleMode.SECOND.equals(_endpoint.getReceivingSettlementMode()); + + if(!(settled || action == null)) + { + _unsettledMap.put(deliveryTag, action); + } + _endpoint.updateAllDisposition(deliveryTag, state, settled); + } + + + + public void close() + { + _endpoint.setTarget(null); + _endpoint.close(); + Message msg; + while((msg = receive(-1l)) != null) + { + release(msg); + } + + } + + + public void detach() + { + _endpoint.setTarget(null); + _endpoint.detach(); + Message msg; + while((msg = receive(-1l)) != null) + { + release(msg); + } + + } + + public void drain() + { + _endpoint.drain(); + } + + public void setCreditWithTransaction(final UnsignedInteger credit, final Transaction txn) + { + _endpoint.setLinkCredit(credit); + _endpoint.setTransactionId(txn == null ? null : txn.getTxnId()); + _endpoint.setCreditWindow(false); + + } + + public void handle(final Binary deliveryTag, final DeliveryState state, final Boolean settled) + { + if(Boolean.TRUE.equals(settled)) + { + SettledAction action = _unsettledMap.remove(deliveryTag); + if(action != null) + { + action.onSettled(deliveryTag); + } + } + } + + public Map getRemoteUnsettled() + { + return _endpoint.getInitialUnsettledMap(); + } + + + public void setMessageArrivalListener(final MessageArrivalListener messageArrivalListener) + { + synchronized(_endpoint.getLock()) + { + _messageArrivalListener = messageArrivalListener; + } + } + + public Session getSession() + { + return _session; + } + + public org.apache.qpid.amqp_1_0.type.Source getSource() + { + return _endpoint.getSource(); + } + + public static interface SettledAction + { + public void onSettled(Binary deliveryTag); + } + + + public interface MessageArrivalListener + { + void messageArrived(Receiver receiver); + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java new file mode 100644 index 0000000000..6e1d15376c --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java @@ -0,0 +1,249 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; +import org.apache.commons.cli.*; + +import java.util.Arrays; + +public class Request extends Util +{ + private static final String USAGE_STRING = "request [options]
[ ...]\n\nOptions:"; + + public static void main(String[] args) + { + new Request(args).run(); + } + + public Request(String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return false; + } + + @Override + protected boolean hasLinkNameOption() + { + return false; + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; + } + + @Override + protected boolean hasSizeOption() + { + return true; + } + + @Override + protected boolean hasBlockOption() + { + return false; + } + + @Override + protected boolean hasStdInOption() + { + return false; + } + + @Override + protected boolean hasTxnOption() + { + return true; + } + + @Override + protected boolean hasModeOption() + { + return true; + } + + @Override + protected boolean hasCountOption() + { + return true; + } + + @Override + protected boolean hasWindowSizeOption() + { + return true; + } + + public void run() + { + + try + { + + + final String queue = getArgs()[0]; + + String message = ""; + + Connection conn = newConnection(); + Session session = conn.createSession(); + + Connection conn2; + Session session2; + Receiver responseReceiver; + + if(isUseMultipleConnections()) + { + conn2 = newConnection(); + session2 = conn2.createSession(); + responseReceiver = session2.createTemporaryQueueReceiver(); + } + else + { + conn2 = null; + session2 = null; + responseReceiver = session.createTemporaryQueueReceiver(); + } + + + + + responseReceiver.setCredit(UnsignedInteger.valueOf(getWindowSize()), true); + + + + Sender s = session.createSender(queue, getWindowSize(), getMode()); + + Transaction txn = null; + + if(useTran()) + { + txn = session.createSessionLocalTransaction(); + } + + int received = 0; + + if(getArgs().length >= 2) + { + message = getArgs()[1]; + if(message.length() < getMessageSize()) + { + StringBuilder builder = new StringBuilder(getMessageSize()); + builder.append(message); + for(int x = message.length(); x < getMessageSize(); x++) + { + builder.append('.'); + } + message = builder.toString(); + } + + for(int i = 0; i < getCount(); i++) + { + Properties properties = new Properties(); + properties.setMessageId(UnsignedLong.valueOf(i)); + properties.setReplyTo(responseReceiver.getAddress()); + + AmqpValue amqpValue = new AmqpValue(message); + Section[] sections = { new Header() , properties, amqpValue}; + final Message message1 = new Message(Arrays.asList(sections)); + + s.send(message1, txn); + + Message responseMessage = responseReceiver.receive(false); + if(responseMessage != null) + { + responseReceiver.acknowledge(responseMessage.getDeliveryTag(),txn); + received++; + } + } + } + + if(txn != null) + { + txn.commit(); + } + + + while(received < getCount()) + { + Message responseMessage = responseReceiver.receive(); + responseReceiver.acknowledge(responseMessage.getDeliveryTag()); + received++; + } + + + + + s.close(); + session.close(); + conn.close(); + + if(session2 != null) + { + session2.close(); + conn2.close(); + } + } + catch (Connection.ConnectionException e) + { + e.printStackTrace(); //TODO. + } + catch (Sender.SenderClosingException e) + { + e.printStackTrace(); //TODO. + } + catch (Sender.SenderCreationException e) + { + e.printStackTrace(); //TODO. + } + catch (AmqpErrorException e) + { + e.printStackTrace(); //TODO. + } + + } + + protected boolean hasSingleLinkPerConnectionMode() + { + return true; + } + + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + } + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java new file mode 100644 index 0000000000..8d9de4893f --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java @@ -0,0 +1,347 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; +import org.apache.commons.cli.*; + +import java.util.*; + +public class Respond extends Util +{ + private static final String USAGE_STRING = "respond [options]
\n\nOptions:"; + private Connection _conn; + private Session _session; + private Receiver _receiver; + private Transaction _txn; + private Map _senders; + private UnsignedLong _responseMsgId = UnsignedLong.ZERO; + private Connection _conn2; + private Session _session2; + + public Respond(final String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return false; + } + + @Override + protected boolean hasLinkNameOption() + { + return false; + } + + @Override + protected boolean hasResponseQueueOption() + { + return true; + } + + @Override + protected boolean hasSizeOption() + { + return false; + } + + @Override + protected boolean hasBlockOption() + { + return true; + } + + @Override + protected boolean hasStdInOption() + { + return false; + } + + @Override + protected boolean hasTxnOption() + { + return true; + } + + @Override + protected boolean hasModeOption() + { + return true; + } + + @Override + protected boolean hasCountOption() + { + return true; + } + + @Override + protected boolean hasSingleLinkPerConnectionMode() + { + return true; + } + + + @Override + protected boolean hasWindowSizeOption() + { + return true; + } + + public static void main(String[] args) + { + new Respond(args).run(); + } + + public void run() + { + try + { + + _senders = new HashMap(); + + final String queue = getArgs()[0]; + + String message = ""; + + _conn = newConnection(); + + + + if(isUseMultipleConnections()) + { + _conn2 = newConnection(); + _session2 = _conn2.createSession(); + } + + + _session = _conn.createSession(); + + + _receiver = _session.createReceiver(queue, getMode()); + _txn = null; + + int credit = 0; + int receivedCount = 0; + _responseMsgId = UnsignedLong.ZERO; + + Random random = null; + int batch = 0; + List txnMessages = null; + if(useTran()) + { + if(getRollbackRatio() != 0) + { + random = new Random(); + } + batch = getBatchSize(); + _txn = _session.createSessionLocalTransaction(); + txnMessages = new ArrayList(batch); + } + + + for(int i = 0; receivedCount < getCount(); i++) + { + + if(credit == 0) + { + if(getCount() - i <= getWindowSize()) + { + credit = getCount() - i; + + } + else + { + credit = getWindowSize(); + + } + + _receiver.setCredit(UnsignedInteger.valueOf(credit), false); + + if(!isBlock()) + _receiver.drain(); + } + + Message m = isBlock() ? (receivedCount == 0 ? _receiver.receive() : _receiver.receive(10000L)) : _receiver.receive(1000L); + credit--; + if(m==null) + { + if(useTran() && batch != getBatchSize()) + { + _txn.commit(); + } + break; + } + + System.out.println("Received Message: " + m.getPayload()); + + respond(m); + + + + if(useTran()) + { + + txnMessages.add(m); + + if(--batch == 0) + { + + if(getRollbackRatio() == 0 || random.nextDouble() >= getRollbackRatio()) + { + _txn.commit(); + txnMessages.clear(); + receivedCount += getBatchSize(); + } + else + { + System.out.println("Random Rollback"); + _txn.rollback(); + double result; + do + { + _txn = _session.createSessionLocalTransaction(); + + for(Message msg : txnMessages) + { + respond(msg); + } + + result = random.nextDouble(); + if(result sections = m.getPayload(); + String replyTo = null; + Object correlationId = null; + for(Section section : sections) + { + if(section instanceof Properties) + { + replyTo = getResponseQueue() == null ? ((Properties)section).getReplyTo() : getResponseQueue(); + correlationId = ((Properties) section).getMessageId(); + break; + } + } + + if(replyTo != null) + { + Sender s = _senders.get(replyTo); + if(s == null) + { + s = (isUseMultipleConnections() ? _session2 : _session).createSender(replyTo,getWindowSize()); + _senders.put(replyTo, s); + } + + List
replySections = new ArrayList
(sections); + + ListIterator
sectionIterator = replySections.listIterator(); + + while(sectionIterator.hasNext()) + { + Section section = sectionIterator.next(); + if(section instanceof Properties) + { + Properties newProps = new Properties(); + newProps.setTo(replyTo); + newProps.setCorrelationId(correlationId); + newProps.setMessageId(_responseMsgId); + _responseMsgId = _responseMsgId.add(UnsignedLong.ONE); + sectionIterator.set(newProps); + } + } + + Message replyMessage = new Message(replySections); + System.out.println("Sent Message: " + replySections); + s.send(replyMessage, _txn); + + } + _receiver.acknowledge(m.getDeliveryTag(), _txn); + } + + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + } + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java new file mode 100644 index 0000000000..6f6575e083 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java @@ -0,0 +1,244 @@ +/* + * + * 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.amqp_1_0.client; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.util.Arrays; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; +import org.apache.qpid.amqp_1_0.type.messaging.Data; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; +import org.apache.commons.cli.*; + +public class Send extends Util +{ + private static final String USAGE_STRING = "send [options]
[ ...]\n\nOptions:"; + private static final char[] HEX = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + + + public static void main(String[] args) throws Sender.SenderCreationException, Sender.SenderClosingException, Connection.ConnectionException + { + new Send(args).run(); + } + + + public Send(final String[] args) + { + super(args); + } + + @Override + protected boolean hasLinkDurableOption() + { + return true; + } + + @Override + protected boolean hasLinkNameOption() + { + return true; + } + + @Override + protected boolean hasResponseQueueOption() + { + return false; + } + + @Override + protected boolean hasSizeOption() + { + return true; + } + + @Override + protected boolean hasBlockOption() + { + return false; + } + + @Override + protected boolean hasStdInOption() + { + return true; + } + + @Override + protected boolean hasTxnOption() + { + return true; + } + + @Override + protected boolean hasModeOption() + { + return true; + } + + @Override + protected boolean hasCountOption() + { + return true; + } + + @Override + protected boolean hasWindowSizeOption() + { + return true; + } + + @Override + protected boolean hasSubjectOption() + { + return true; + } + + public void run() + { + + final String queue = getArgs()[0]; + + String message = ""; + + try + { + Connection conn = newConnection(); + + Session session = conn.createSession(); + + + Sender s = session.createSender(queue, getWindowSize(), getMode(), getLinkName()); + + Transaction txn = null; + + if(useTran()) + { + txn = session.createSessionLocalTransaction(); + } + + if(!useStdIn()) + { + if(getArgs().length <= 2) + { + if(getArgs().length == 2) + { + message = getArgs()[1]; + } + for(int i = 0; i < getCount(); i++) + { + + Properties properties = new Properties(); + properties.setMessageId(UnsignedLong.valueOf(i)); + if(getSubject() != null) + { + properties.setSubject(getSubject()); + } + Section bodySection; + byte[] bytes = (message + " " + i).getBytes(); + if(bytes.length < getMessageSize()) + { + byte[] origBytes = bytes; + bytes = new byte[getMessageSize()]; + System.arraycopy(origBytes,0,bytes,0,origBytes.length); + for(int x = origBytes.length; x < bytes.length; x++) + { + bytes[x] = (byte) '.'; + } + bodySection = new Data(new Binary(bytes)); + } + else + { + bodySection = new AmqpValue(message + " " + i); + } + + Section[] sections = {properties, bodySection}; + final Message message1 = new Message(Arrays.asList(sections)); + + s.send(message1, txn); + } + } + else + { + for(int i = 1; i < getArgs().length; i++) + { + s.send(new Message(getArgs()[i]), txn); + } + + } + } + else + { + LineNumberReader buf = new LineNumberReader(new InputStreamReader(System.in)); + + + try + { + while((message = buf.readLine()) != null) + { + s.send(new Message(message), txn); + } + } + catch (IOException e) + { + // TODO + e.printStackTrace(); + } + } + + if(txn != null) + { + txn.commit(); + } + + s.close(); + + session.close(); + conn.close(); + } + catch (Sender.SenderClosingException e) + { + e.printStackTrace(); //TODO. + } + catch (Connection.ConnectionException e) + { + e.printStackTrace(); //TODO. + } + catch (Sender.SenderCreationException e) + { + e.printStackTrace(); //TODO. + } + + + } + + protected void printUsage(Options options) + { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp(USAGE_STRING, options ); + } + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java new file mode 100644 index 0000000000..6f97ecd810 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java @@ -0,0 +1,331 @@ +/* + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.codec.FrameWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.framing.AMQFrame; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.FrameBody; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedByte; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.UnsignedShort; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; +import org.apache.qpid.amqp_1_0.type.messaging.Footer; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.Properties; +import org.apache.qpid.amqp_1_0.type.transport.Flow; + +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class SendBytes +{ + + public static void main(String[] args) throws + Sender.SenderCreationException, + Sender.SenderClosingException, + Connection.ConnectionException, + IOException, ParseException + { + Transfer xfr = new Transfer(); + Flow fs = new Flow(); + fs.setIncomingWindow(UnsignedInteger.valueOf(1024)); + fs.setDeliveryCount(UnsignedInteger.valueOf(2)); + fs.setLinkCredit(UnsignedInteger.valueOf(18)); + fs.setAvailable(UnsignedInteger.valueOf(0)); + fs.setDrain(false); + + xfr.setHandle(UnsignedInteger.valueOf(0)); + xfr.setDeliveryTag(new Binary("\"queue\"<-6ec024a7-d98e-4196-9348-15f6026c32ca:0".getBytes())); + //xfr.setDeliveryTag(new Binary(new byte[] {0})); + xfr.setDeliveryId(UnsignedInteger.valueOf(0)); + xfr.setSettled(true); + + + Header h = new Header(); + Properties p = new Properties(); + p.setTo("queue"); + //p.setMessageId(new Binary(UUID.randomUUID().toString().getBytes())); + + Footer f = new Footer(Collections.EMPTY_MAP); + + Section[] sections = new Section[] { h,p,f}; + //Section[] sections = new Section[] { b }; + //Section[] sections = { h,p, b}; +/* + Fragment[] fragments = new Fragment[5]; + + final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance().registerTransportLayer().registerMessagingLayer(); + + SectionEncoderImpl encoder = new SectionEncoderImpl(typeRegistry); + + int num = 0; + int i = 0; + for(Section s : sections) + { + Fragment frag = new Fragment(); + + frag.setPayload(s.encode(encoder)); + frag.setFirst(true); + frag.setLast(true); + frag.setSectionCode(s.getSectionCode()); + frag.setSectionNumber(UnsignedInteger.valueOf(num++)); + frag.setSectionOffset(UnsignedLong.valueOf(0L)); + fragments[i++] =frag; + } + + xfr.setFragments(fragments); +*/ + + encodeTypes("xfr",xfr); + + final byte[] result; + final Object input = xfr; +/* + result = encode(1024, input); + + boolean ok = true; + + for(int j = 10; ok && j < 400; j++) + { + + byte[] result2 = encode(j,input); + + for(int i = 0; i <400; i++) + { + if(result[i] != result2[i]) + { + System.out.println("result differs at " + i + " Splitting at " + j+ " [" + result[i] + " - " + result2[i] + "]"); + //break; + //ok = false; + + } + } + }*/ + //System.out.println(Arrays.equals(result, result2)); + + //doEncodes(); + /*OutputStream out = System.out; + if(args.length > 0) + { + out = new FileOutputStream(args[0]); + } + + Transfer xfr = new Transfer(); + fs.setSessionCredit(UnsignedInteger.valueOf(1024)); + fs.setTransferCount(UnsignedInteger.valueOf(2)); + fs.setLinkCredit(UnsignedInteger.valueOf(18)); + fs.setAvailable(UnsignedInteger.valueOf(0)); + fs.setDrain(false); + + xfr.setHandle(UnsignedInteger.valueOf(0)); + //xfr.setDeliveryTag(new Binary("\"queue\"<-6ec024a7-d98e-4196-9348-15f6026c32ca:0".getBytes())); + xfr.setDeliveryTag(new Binary(new byte[] {0})); + xfr.setTransferId(UnsignedInteger.valueOf(0)); + xfr.setSettled(true); + xfr.setFlowState(fs); + + Header h = new Header(); + h.setTransmitTime(new Date(System.currentTimeMillis())); + Properties p = new Properties(); + p.setTo(new Address("queue")); + //p.setMessageId(new Binary(UUID.randomUUID().toString().getBytes())); + AmqpMapSection m = new AmqpMapSection(); + DataSection b = new DataSection("Hello World!".getBytes()); + + Footer f = new Footer(); + + Section[] sections = new Section[] { h,p,m,b,f}; + //Section[] sections = new Section[] { b }; + //Section[] sections = { h,p, b}; + List fragments = new ArrayList(5); + + final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + + SectionEncoderImpl encoder = new SectionEncoderImpl(typeRegistry); + + for(Section s : sections) + { + Fragment frag = new Fragment(); + + frag.setPayload(s.encode(encoder)); + frag.setFirst(true); + frag.setLast(true); + frag.setFormatCode(s.getSectionCode()); + frag.setFragmentOffset(null); + fragments.add(frag); + } + + xfr.setFragments(fragments); + + + Object[] objectsToWrite = new Object[] { xfr }; + ByteBuffer buf = ByteBuffer.allocate(4096); + + + for(Object obj : objectsToWrite) + { + ValueWriter writer = typeRegistry.getValueWriter(obj); + + int count; + + + do + { + count = writer.writeToBuffer(buf); + out.write(buf.array(), buf.arrayOffset(), count); + buf.clear(); + } while (!writer.isComplete()); + + } + + out.flush(); + out.close();*/ + + } + + public static void doEncodes() throws IOException, ParseException + { + encodeTypes("boolean", Boolean.TRUE, Boolean.FALSE); + encodeTypes("ubyte", UnsignedByte.valueOf((byte)0), UnsignedByte.valueOf((byte)1 ),UnsignedByte.valueOf((byte)3), UnsignedByte.valueOf((byte)42), UnsignedByte.valueOf("255")); + encodeTypes("byte", Byte.valueOf((byte)0), Byte.valueOf( (byte)1), Byte.valueOf((byte) 3), Byte.valueOf((byte) 42), Byte.valueOf((byte) 127), Byte.valueOf((byte) -1), Byte.valueOf((byte) -3), Byte.valueOf((byte) -42), Byte.valueOf( (byte)-128)); + encodeTypes("ushort", UnsignedShort.valueOf((short)0), UnsignedShort.valueOf((short)1), UnsignedShort.valueOf((short)3), UnsignedShort.valueOf((short)42), UnsignedShort.valueOf("65535")); + encodeTypes("short", Short.valueOf((short)0), Short.valueOf((short)1), Short.valueOf((short)3), Short.valueOf((short)42), Short.valueOf((short)32767), Short.valueOf((short)-1), Short.valueOf((short)-3), Short.valueOf((short)-42), Short.valueOf((short)-32768)); + encodeTypes("uint",UnsignedInteger.valueOf(0), UnsignedInteger.valueOf(1), UnsignedInteger.valueOf(3), UnsignedInteger.valueOf(42), UnsignedInteger.valueOf("4294967295")); + encodeTypes("int", 0, 1, 3, 42, 2147483647, -1, -3, -42, -2147483648); + encodeTypes("ulong", UnsignedLong.valueOf(0), UnsignedLong.valueOf(1), UnsignedLong.valueOf(3), UnsignedLong.valueOf(42), UnsignedLong.valueOf("18446744073709551615")); + encodeTypes("long", 0l, 1l, 3l, 42l, 9223372036854775807l, -1l, -3l, -42l, -9223372036854775808l); + encodeTypes("float", 3.14159); + encodeTypes("double", Double.valueOf(3.14159265359)); + encodeTypes("char", '?'); + + SimpleDateFormat df = new SimpleDateFormat("HHa z MMM d yyyy"); + + encodeTypes("timestamp", df.parse("9AM PST Dec 6 2010"), df.parse("9AM PST Dec 6 1910")); + encodeTypes("uuid", UUID.fromString("f275ea5e-0c57-4ad7-b11a-b20c563d3b71")); + encodeTypes("binary", new Binary( new byte[] {(byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF}), new Binary(new byte[] { (byte)0xCA,(byte)0xFE, (byte)0xBA, (byte)0xBE})); + encodeTypes("string", "The quick brown fox jumped over the lazy cow."); + encodeTypes("symbol", Symbol.valueOf("connectathon")); + encodeTypes("list", Arrays.asList(new Object[] {Long.valueOf(1), "two", Double.valueOf(3.14159265359), null, Boolean.FALSE})); + Map map = new HashMap(); + map.put("one", Long.valueOf(1)); + map.put("two", Long.valueOf(2)); + map.put("pi", Double.valueOf(3.14159265359)); + map.put("list:", Arrays.asList(new Object[] {Long.valueOf(1), "two", Double.valueOf(3.14159265359), null, Boolean.FALSE})); + map.put(null, Boolean.TRUE); + encodeTypes("map", map); + encodeTypes("null", null); + + } + + static void encodeTypes(String name, Object... vals ) throws IOException + { + FileOutputStream out = new FileOutputStream("/home/rob/"+name+".out"); + ByteBuffer buf = ByteBuffer.allocate(4096); + final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + + if(vals != null) + { + for(Object obj : vals) + { + ValueWriter writer = typeRegistry.getValueWriter(obj); + + int count; + + + do + { + count = writer.writeToBuffer(buf); + out.write(buf.array(), buf.arrayOffset(), count); + buf.clear(); + } while (!writer.isComplete()); + + } + } + else + { + ValueWriter writer = typeRegistry.getValueWriter(null); + + int count; + + + do + { + count = writer.writeToBuffer(buf); + out.write(buf.array(), buf.arrayOffset(), count); + buf.clear(); + } while (!writer.isComplete()); + + } + out.flush(); + out.close(); + + } + + static byte[] encode(int size, Object... vals) + { + byte[] result = new byte[10000]; + int pos = 0; + + final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + AMQFrame frame = AMQFrame.createAMQFrame((short) 0, (FrameBody) vals[0]); + FrameWriter writer = new FrameWriter(typeRegistry); + /*for(Object obj : vals) + { + final AMQPDescribedTypeRegistry typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + ValueWriter writer = typeRegistry.getValueWriter(obj); +*/ + int count; + + ByteBuffer buf = ByteBuffer.wrap(result, pos, size); + + do + { + + writer.writeToBuffer(buf); + pos = buf.position(); + buf = ByteBuffer.wrap(result, pos, size); + if(!writer.isComplete()) + { + count = 3; + } + + } while (!writer.isComplete()); +/* + + } +*/ + + return result; + + } + + +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java new file mode 100644 index 0000000000..c20eec6c8e --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java @@ -0,0 +1,392 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; +import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler; +import org.apache.qpid.amqp_1_0.transport.SendingLinkEndpoint; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.Source; +import org.apache.qpid.amqp_1_0.type.Target; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.transaction.TransactionalState; +import org.apache.qpid.amqp_1_0.type.transport.*; + +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Sender implements DeliveryStateHandler +{ + private SendingLinkEndpoint _endpoint; + private int _id; + private Session _session; + private int _windowSize; + private Map _outcomeActions = Collections.synchronizedMap(new HashMap()); + private boolean _closed; + + public Sender(final Session session, final String linkName, final String targetAddr, final String sourceAddr) + throws SenderCreationException + { + this(session, linkName, targetAddr, sourceAddr, false); + } + + public Sender(final Session session, final String linkName, final String targetAddr, final String sourceAddr, + boolean synchronous) + throws SenderCreationException + { + this(session, linkName, targetAddr, sourceAddr, synchronous ? 1 : 0); + } + + public Sender(final Session session, final String linkName, final String targetAddr, final String sourceAddr, + int window) throws SenderCreationException + { + this(session, linkName, targetAddr, sourceAddr, window, AcknowledgeMode.ALO); + } + + + public Sender(final Session session, final String linkName, final org.apache.qpid.amqp_1_0.type.messaging.Target target, final org.apache.qpid.amqp_1_0.type.messaging.Source source, + int window) throws SenderCreationException + { + this(session, linkName, target, source, window, AcknowledgeMode.ALO); + } + + public Sender(final Session session, final String linkName, final String targetAddr, final String sourceAddr, + int window, AcknowledgeMode mode) + throws SenderCreationException + { + this(session, linkName, targetAddr, sourceAddr, window, mode, null); + } + + public Sender(final Session session, final String linkName, final org.apache.qpid.amqp_1_0.type.messaging.Target target, final org.apache.qpid.amqp_1_0.type.messaging.Source source, + int window, AcknowledgeMode mode) + throws SenderCreationException + { + this(session, linkName, target, source, window, mode, null); + } + + public Sender(final Session session, final String linkName, final String targetAddr, final String sourceAddr, + int window, AcknowledgeMode mode, Map unsettled) + throws SenderCreationException + { + this(session, linkName, targetAddr, sourceAddr, window, mode, false, unsettled); + } + + public Sender(final Session session, final String linkName, final String targetAddr, final String sourceAddr, + int window, AcknowledgeMode mode, boolean isDurable, Map unsettled) + throws SenderCreationException + { + this(session, linkName, createTarget(targetAddr, isDurable), createSource(sourceAddr), window, mode, unsettled); + } + + private static org.apache.qpid.amqp_1_0.type.messaging.Source createSource(final String sourceAddr) + { + org.apache.qpid.amqp_1_0.type.messaging.Source source = new org.apache.qpid.amqp_1_0.type.messaging.Source(); + source.setAddress(sourceAddr); + return source; + } + + private static org.apache.qpid.amqp_1_0.type.messaging.Target createTarget(final String targetAddr, final boolean isDurable) + { + org.apache.qpid.amqp_1_0.type.messaging.Target target = new org.apache.qpid.amqp_1_0.type.messaging.Target(); + target.setAddress(targetAddr); + if(isDurable) + { + target.setDurable(TerminusDurability.UNSETTLED_STATE); + target.setExpiryPolicy(TerminusExpiryPolicy.NEVER); + } + return target; + } + + public Sender(final Session session, final String linkName, final org.apache.qpid.amqp_1_0.type.messaging.Target target, final org.apache.qpid.amqp_1_0.type.messaging.Source source, + int window, AcknowledgeMode mode, Map unsettled) + throws SenderCreationException + { + + _session = session; + _endpoint = session.getEndpoint().createSendingLinkEndpoint(linkName, + source, target, unsettled); + + + switch(mode) + { + case ALO: + _endpoint.setSendingSettlementMode(SenderSettleMode.UNSETTLED); + _endpoint.setReceivingSettlementMode(ReceiverSettleMode.FIRST); + break; + case AMO: + _endpoint.setSendingSettlementMode(SenderSettleMode.SETTLED); + break; + case EO: + _endpoint.setSendingSettlementMode(SenderSettleMode.UNSETTLED); + _endpoint.setReceivingSettlementMode(ReceiverSettleMode.SECOND); + break; + + } + _endpoint.setDeliveryStateHandler(this); + _endpoint.attach(); + _windowSize = window; + + synchronized(_endpoint.getLock()) + { + while(!(_endpoint.isAttached() || _endpoint.isDetached())) + { + try + { + _endpoint.getLock().wait(); + } + catch (InterruptedException e) + { + throw new SenderCreationException(e); + } + } + if(_endpoint.getTarget()== null) + { + throw new SenderCreationException("Peer did not create remote endpoint for link, target: " + target.getAddress()); + }; + } + } + + public Source getSource() + { + return _endpoint.getSource(); + } + + public Target getTarget() + { + return _endpoint.getTarget(); + } + + public void send(Message message) + { + send(message, null, null); + } + + public void send(Message message, final OutcomeAction action) + { + send(message, null, action); + } + + public void send(Message message, final Transaction txn) + { + send(message, txn, null); + } + + public void send(Message message, final Transaction txn, OutcomeAction action) + { + + List
sections = message.getPayload(); + + Transfer xfr = new Transfer(); + + if(sections != null && !sections.isEmpty()) + { + SectionEncoder encoder = _session.getSectionEncoder(); + encoder.reset(); + + int sectionNumber = 0; + for(Section section : sections) + { + encoder.encodeObject(section); + } + + + Binary encoding = encoder.getEncoding(); + ByteBuffer payload = encoding.asByteBuffer(); + xfr.setPayload(payload); + } + if(message.getDeliveryTag() == null) + { + message.setDeliveryTag(new Binary(String.valueOf(_id++).getBytes())); + } + if(message.isResume()) + { + xfr.setResume(Boolean.TRUE); + } + if(message.getDeliveryState() != null) + { + xfr.setState(message.getDeliveryState()); + } + + xfr.setDeliveryTag(message.getDeliveryTag()); + //xfr.setSettled(_windowSize ==0); + if(txn != null) + { + xfr.setSettled(false); + TransactionalState deliveryState = new TransactionalState(); + deliveryState.setTxnId(txn.getTxnId()); + xfr.setState(deliveryState); + } + else + { + xfr.setSettled(message.getSettled() || _endpoint.getSendingSettlementMode() == SenderSettleMode.SETTLED); + } + final Object lock = _endpoint.getLock(); + synchronized(lock) + { + while(!_endpoint.hasCreditToSend()) + { + try + { + lock.wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + if(action != null) + { + _outcomeActions.put(message.getDeliveryTag(), action); + } + _endpoint.transfer(xfr); + //TODO - rationalise sending of flows + // _endpoint.sendFlow(); + } + + if(_windowSize != 0) + { + synchronized(lock) + { + + + while(_endpoint.getUnsettledCount() >= _windowSize) + { + try + { + lock.wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + + } + + + } + + public void close() throws SenderClosingException + { + + if(_windowSize != 0) + { + synchronized(_endpoint.getLock()) + { + + + while(_endpoint.getUnsettledCount() > 0) + { + try + { + _endpoint.getLock().wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + + } + _session.removeSender(this); + _endpoint.setSource(null); + _endpoint.detach(); + _closed = true; + + synchronized(_endpoint.getLock()) + { + while(!_endpoint.isDetached()) + { + try + { + _endpoint.getLock().wait(); + } + catch (InterruptedException e) + { + throw new SenderClosingException(e); + } + } + } + } + + public boolean isClosed() + { + return _closed; + } + + public void handle(Binary deliveryTag, DeliveryState state, Boolean settled) + { + if(state instanceof Outcome) + { + OutcomeAction action; + if((action = _outcomeActions.remove(deliveryTag)) != null) + { + action.onOutcome(deliveryTag, (Outcome) state); + } + if(!Boolean.TRUE.equals(settled)) + { + _endpoint.updateDisposition(deliveryTag, state, true); + } + } + } + + public Map getRemoteUnsettled() + { + return _endpoint.getInitialUnsettledMap(); + } + + public Session getSession() + { + return _session; + } + + public class SenderCreationException extends Exception + { + public SenderCreationException(Throwable e) + { + super(e); + } + + public SenderCreationException(String e) + { + super(e); + + } + } + + public class SenderClosingException extends Exception + { + public SenderClosingException(Throwable e) + { + super(e); + } + } + + public static interface OutcomeAction + { + public void onOutcome(Binary deliveryTag, Outcome outcome); + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Session.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Session.java new file mode 100644 index 0000000000..5e1e1b1d7c --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Session.java @@ -0,0 +1,354 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.messaging.SectionDecoder; +import org.apache.qpid.amqp_1_0.messaging.SectionDecoderImpl; +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; +import org.apache.qpid.amqp_1_0.messaging.SectionEncoderImpl; +import org.apache.qpid.amqp_1_0.transport.SendingLinkEndpoint; +import org.apache.qpid.amqp_1_0.transport.SessionEndpoint; +import org.apache.qpid.amqp_1_0.transport.SessionState; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.Filter; +import org.apache.qpid.amqp_1_0.type.messaging.Source; +import org.apache.qpid.amqp_1_0.type.messaging.StdDistMode; +import org.apache.qpid.amqp_1_0.type.messaging.Target; +import org.apache.qpid.amqp_1_0.type.transaction.TxnCapability; +import org.apache.qpid.amqp_1_0.type.transport.ReceiverSettleMode; +import org.apache.qpid.amqp_1_0.type.transport.SenderSettleMode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +public class Session +{ + private SessionEndpoint _endpoint; + private List _receivers = new ArrayList(); + private List _senders = new ArrayList(); + private SectionEncoder _sectionEncoder; + private SectionDecoder _sectionDecoder; + private TransactionController _sessionLocalTC; + private Connection _connection; + + public Session(final Connection connection, String name) + { + _connection = connection; + _endpoint = connection.getEndpoint().createSession(name); + _sectionEncoder = new SectionEncoderImpl(connection.getEndpoint().getDescribedTypeRegistry()); + _sectionDecoder = new SectionDecoderImpl(connection.getEndpoint().getDescribedTypeRegistry()); + } + + + public synchronized Sender createSender(final String targetName) throws Sender.SenderCreationException + { + return createSender(targetName, false); + } + + public synchronized Sender createSender(final String targetName, boolean synchronous) throws Sender.SenderCreationException + { + + final String sourceName = UUID.randomUUID().toString(); + return new Sender(this, targetName+"<-"+sourceName, targetName, sourceName, synchronous); + + } + + public synchronized Sender createSender(final String targetName, int window) throws Sender.SenderCreationException + { + final String sourceName = UUID.randomUUID().toString(); + return new Sender(this, targetName+"<-"+sourceName, targetName, sourceName, window); + + } + + public Sender createSender(String targetName, int window, AcknowledgeMode mode) throws Sender.SenderCreationException + { + + return createSender(targetName, window, mode, null); + } + + public Sender createSender(String targetName, int window, AcknowledgeMode mode, String linkName) throws Sender.SenderCreationException + { + return createSender(targetName, window, mode, linkName, null); + } + public Sender createSender(String targetName, int window, AcknowledgeMode mode, String linkName, Map unsettled) throws Sender.SenderCreationException + { + return createSender(targetName, window, mode, linkName, false, unsettled); + } + + public Sender createSender(String targetName, int window, AcknowledgeMode mode, String linkName, + boolean isDurable, Map unsettled) throws Sender.SenderCreationException + { + return new Sender(this, linkName == null ? "->" + targetName + '(' + UUID.randomUUID().toString()+')': linkName, + targetName, null, window, mode, isDurable, unsettled); + + } + + + public Receiver createReceiver(final String sourceAddr) throws AmqpErrorException + { + return createReceiver(sourceAddr, null, AcknowledgeMode.ALO); + } + + + public Receiver createReceiver(final String queue, final AcknowledgeMode mode) throws AmqpErrorException + { + return createReceiver(queue, null, mode); + } + + public Receiver createReceiver(final String queue, final AcknowledgeMode mode, String linkName) + throws AmqpErrorException + { + return createReceiver(queue, null, mode, linkName); + } + + public Receiver createReceiver(final String queue, final AcknowledgeMode mode, String linkName, boolean isDurable) + throws AmqpErrorException + { + return createReceiver(queue, null, mode, linkName, isDurable); + } + + public Receiver createReceiver(final String queue, final AcknowledgeMode mode, String linkName, boolean isDurable, + Map filters, Map unsettled) + throws AmqpErrorException + { + return createReceiver(queue, null, mode, linkName, isDurable, filters, unsettled); + } + + + public Receiver createReceiver(final String queue, final AcknowledgeMode mode, String linkName, + boolean isDurable, Map unsettled) throws AmqpErrorException + { + return createReceiver(queue, null, mode, linkName, isDurable, unsettled); + } + + + private synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode) + throws AmqpErrorException + { + return createReceiver(sourceAddr, mode, AcknowledgeMode.ALO); + } + + private synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode, String linkName) + throws AmqpErrorException + { + return createReceiver(sourceAddr, mode, AcknowledgeMode.ALO, linkName); + } + + + private synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode, + final AcknowledgeMode ackMode) throws AmqpErrorException + { + return createReceiver(sourceAddr, mode, ackMode, null); + } + + private synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode, + final AcknowledgeMode ackMode, String linkName) throws AmqpErrorException + { + return createReceiver(sourceAddr,mode, ackMode, linkName, false); + } + + private synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode, + final AcknowledgeMode ackMode, String linkName, boolean isDurable) + throws AmqpErrorException + { + return createReceiver(sourceAddr, mode, ackMode, linkName, isDurable, null); + } + + private synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode, + final AcknowledgeMode ackMode, String linkName, boolean isDurable, + Map unsettled) throws AmqpErrorException + { + return createReceiver(sourceAddr,mode,ackMode, linkName, isDurable, null, unsettled); + } + + public synchronized Receiver createReceiver(final String sourceAddr, DistributionMode mode, + final AcknowledgeMode ackMode, String linkName, boolean isDurable, + Map filters, Map unsettled) + throws AmqpErrorException + { + + final Target target = new Target(); + final Source source = new Source(); + source.setAddress(sourceAddr); + source.setDistributionMode(mode); + source.setFilter(filters); + + if(linkName == null) + { + linkName = sourceAddr + "-> (" + UUID.randomUUID().toString() + ")"; + } + + final Receiver receiver = + new Receiver(this, linkName, + target, source, ackMode, isDurable, unsettled); + _receivers.add(receiver); + + return receiver; + + } + + public synchronized Receiver createCopyingReceiver(final String sourceAddr) throws AmqpErrorException + { + return createReceiver(sourceAddr, StdDistMode.COPY); + } + + public synchronized Receiver createMovingReceiver(final String sourceAddr) throws AmqpErrorException + { + return createReceiver(sourceAddr, StdDistMode.MOVE); + } + + public Receiver createTemporaryQueueReceiver() throws AmqpErrorException + { + Source source = new Source(); + source.setDynamic(true); + + final Receiver receiver = new Receiver(this, "tempSender"+UUID.randomUUID().toString(), new Target(), + source, AcknowledgeMode.ALO); + _receivers.add(receiver); + return receiver; + } + + public Sender createTemporaryQueueSender() throws Sender.SenderCreationException + { + Target target = new Target(); + target.setDynamic(true); + + final Sender sender; + sender = new Sender(this, "tempSender"+ UUID.randomUUID().toString(), target, + new Source(), 0, AcknowledgeMode.ALO); + _senders.add(sender); + return sender; + } + + + + public SessionEndpoint getEndpoint() + { + return _endpoint; + } + + public synchronized void close() + { + try + { + for(Sender sender : new ArrayList(_senders)) + { + sender.close(); + } + for(Receiver receiver : new ArrayList(_receivers)) + { + receiver.detach(); + } + if(_sessionLocalTC != null) + { + _sessionLocalTC.close(); + } + _endpoint.end(); + } + catch (Sender.SenderClosingException e) + { +// TODO + e.printStackTrace(); + } + + //TODO + + } + + void removeSender(Sender sender) + { + _senders.remove(sender); + } + + void removeReceiver(Receiver receiver) + { + _receivers.remove(receiver); + } + + public SectionEncoder getSectionEncoder() + { + return _sectionEncoder; + } + + public SectionDecoder getSectionDecoder() + { + return _sectionDecoder; + } + + + public Transaction createSessionLocalTransaction() + { + TransactionController localController = getSessionLocalTransactionController(); + return localController.beginTransaction(); + } + + private TransactionController getSessionLocalTransactionController() + { + if(_sessionLocalTC == null) + { + _sessionLocalTC = createSessionLocalTransactionController(); + } + return _sessionLocalTC; + } + + private TransactionController createSessionLocalTransactionController() + { + String name = "txnControllerLink"; + SendingLinkEndpoint tcLinkEndpoint = _endpoint.createTransactionController(name, TxnCapability.LOCAL_TXN, + TxnCapability.MULTI_TXNS_PER_SSN); + tcLinkEndpoint.setReceivingSettlementMode(ReceiverSettleMode.FIRST); + tcLinkEndpoint.setSendingSettlementMode(SenderSettleMode.UNSETTLED); + tcLinkEndpoint.attach(); + return new TransactionController(this, tcLinkEndpoint); + } + + + public Message receive() + { + while(getEndpoint().getState() == SessionState.ACTIVE) + { + synchronized (getEndpoint().getLock()) + { + try + { + for(Receiver r : _receivers) + { + Message m = r.receive(false); + if(m != null) + return m; + } + wait(); + } + catch (InterruptedException e) + { + } + } + } + return null; + } + + public Connection getConnection() + { + return _connection; + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Transaction.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Transaction.java new file mode 100644 index 0000000000..a379463710 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Transaction.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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.type.Binary; + +public class Transaction +{ + private TransactionController _transactionController; + private Binary _txnId; + + Transaction(final TransactionController transactionController, Binary txnId) + { + _transactionController = transactionController; + _txnId = txnId; + } + + public void commit() + { + _transactionController.commit(this); + } + + public void rollback() + { + _transactionController.rollback(this); + } + + public Binary getTxnId() + { + return _txnId; + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransactionController.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransactionController.java new file mode 100644 index 0000000000..9f2c76bc72 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransactionController.java @@ -0,0 +1,194 @@ +/* + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; +import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler; +import org.apache.qpid.amqp_1_0.transport.SendingLinkEndpoint; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.DeliveryState; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; +import org.apache.qpid.amqp_1_0.type.transaction.Declare; +import org.apache.qpid.amqp_1_0.type.transaction.Declared; +import org.apache.qpid.amqp_1_0.type.transaction.Discharge; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + + +public class TransactionController implements DeliveryStateHandler +{ + private static final Binary DELIVERY_TAG = new Binary(new byte[]{(byte) 0}); + private SendingLinkEndpoint _endpoint; + private Session _session; + private volatile DeliveryState _state; + private boolean _received; + + public TransactionController(Session session, SendingLinkEndpoint tcLinkEndpoint) + { + _session = session; + _endpoint = tcLinkEndpoint; + _endpoint.setDeliveryStateHandler(this); + } + + public Transaction beginTransaction() + { + + + Binary txnId = declare(); + return new Transaction(this, txnId); + } + + private Binary declare() + { + SectionEncoder encoder = _session.getSectionEncoder(); + + + AmqpValue section = new AmqpValue(new Declare()); + + + Transfer transfer = new Transfer(); + transfer.setPayload(section.encode(encoder).asByteBuffer()); + transfer.setDeliveryTag(DELIVERY_TAG); + transfer.setSettled(Boolean.FALSE); + final Object lock = _endpoint.getLock(); + synchronized(lock) + { + while(!_endpoint.hasCreditToSend()) + { + try + { + lock.wait(); + } + catch (InterruptedException e) + { + + } + } + _state = null; + _received = false; + _endpoint.transfer(transfer); + + //TODO - rationalise sending of flows + // _endpoint.sendFlow(); + } + synchronized (this) + { + while(!_received) + { + try + { + wait(); + } + catch (InterruptedException e) + { + + } + } + } + + + return ((Declared) _state).getTxnId(); + } + + + public void commit(final Transaction transaction) + { + discharge(transaction.getTxnId(), false); + } + + public void rollback(final Transaction transaction) + { + discharge(transaction.getTxnId(), true); + } + + private void discharge(final Binary txnId, final boolean fail) + { + Discharge discharge = new Discharge(); + discharge.setTxnId(txnId); + discharge.setFail(fail); + SectionEncoder encoder = _session.getSectionEncoder(); + + + AmqpValue section = new AmqpValue(discharge); + + Transfer transfer = new Transfer(); + transfer.setPayload(section.encode(encoder).asByteBuffer()); + transfer.setDeliveryTag(DELIVERY_TAG); + transfer.setSettled(Boolean.FALSE); + + final Object lock = _endpoint.getLock(); + synchronized(lock) + { + while(!_endpoint.hasCreditToSend()) + { + try + { + lock.wait(); + } + catch (InterruptedException e) + { + + } + } + _state = null; + _received = false; + _endpoint.transfer(transfer); + + //TODO - rationalise sending of flows + // _endpoint.sendFlow(); + } + synchronized (this) + { + while(!_received) + { + try + { + wait(); + } + catch (InterruptedException e) + { + + } + } + } + + + } + + public void handle(final Binary deliveryTag, final DeliveryState state, final Boolean settled) + { + synchronized(this) + { + _state = state; + _received = true; + + if(!Boolean.TRUE.equals(settled)) + { + _endpoint.updateDisposition(deliveryTag, state, true); + } + + notifyAll(); + } + } + + public void close() + { + _endpoint.close(); + } +} diff --git a/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java new file mode 100644 index 0000000000..6fe2a6d510 --- /dev/null +++ b/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java @@ -0,0 +1,529 @@ +/* + * + * 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.amqp_1_0.client; + +import org.apache.qpid.amqp_1_0.transport.Container; +import org.apache.commons.cli.*; + +import java.util.logging.*; + +public abstract class Util +{ + + private static final Logger FRAME_LOGGER = Logger.getLogger("FRM"); + private static final Logger RAW_LOGGER = Logger.getLogger("RAW"); + private String _host; + private String _username; + private String _password; + private int _port; + private int _count; + private boolean _useStdIn; + private boolean _useTran; + private String[] _args; + private AcknowledgeMode _mode; + private boolean _block; + private int _frameSize; + private int _messageSize; + private String _responseQueue; + private int _batchSize; + private double _rollbackRatio; + private String _linkName; + private String _containerName; + private boolean _durableLink; + private boolean _useMultipleConnections; + private int _windowSize = 100; + private String _subject; + private String _filter; + private String _remoteHost; + private boolean _useSSL; + + protected Util(String[] args) + { + CommandLineParser cmdLineParse = new PosixParser(); + + Options options = new Options(); + options.addOption("h","help",false,"show this help message and exit"); + options.addOption(OptionBuilder.withLongOpt("host") + .withDescription( "host to connect to (default 0.0.0.0)" ) + .hasArg(true) + .withArgName("HOST") + .create('H')); + options.addOption(OptionBuilder.withLongOpt("username") + .withDescription( "username to use for authentication" ) + .hasArg(true) + .withArgName("USERNAME") + .create('u')); + options.addOption(OptionBuilder.withLongOpt("password") + .withDescription( "password to use for authentication" ) + .hasArg(true) + .withArgName("PASSWORD") + .create('w')); + options.addOption(OptionBuilder.withLongOpt("port") + .withDescription( "port to connect to (default 5672)" ) + .hasArg(true) + .withArgName("PORT") + .create('p')); + options.addOption(OptionBuilder.withLongOpt("frame-size") + .withDescription( "specify the maximum frame size" ) + .hasArg(true) + .withArgName("FRAME_SIZE") + .create('f')); + options.addOption(OptionBuilder.withLongOpt("container-name") + .withDescription( "Container name" ) + .hasArg(true) + .withArgName("CONTAINER_NAME") + .create('C')); + + options.addOption(OptionBuilder.withLongOpt("ssl") + .withDescription("Use SSL") + .create('S')); + + options.addOption(OptionBuilder.withLongOpt("remote-hostname") + .withDescription( "hostname to supply in the open frame" ) + .hasArg(true) + .withArgName("HOST") + .create('O')); + + if(hasBlockOption()) + options.addOption(OptionBuilder.withLongOpt("block") + .withDescription("block until messages arrive") + .create('b')); + + if(hasCountOption()) + options.addOption(OptionBuilder.withLongOpt("count") + .withDescription( "number of messages to send (default 1)" ) + .hasArg(true) + .withArgName("COUNT") + .create('c')); + if(hasModeOption()) + options.addOption(OptionBuilder.withLongOpt("acknowledge-mode") + .withDescription( "acknowledgement mode: AMO|ALO|EO (At Least Once, At Most Once, Exactly Once" ) + .hasArg(true) + .withArgName("MODE") + .create('k')); + + if(hasSubjectOption()) + options.addOption(OptionBuilder.withLongOpt("subject") + .withDescription( "subject message property" ) + .hasArg(true) + .withArgName("SUBJECT") + .create('s')); + + + if(hasSingleLinkPerConnectionMode()) + options.addOption(OptionBuilder.withLongOpt("single-link-per-connection") + .withDescription("acknowledgement mode: AMO|ALO|EO (At Least Once, At Most Once, Exactly Once") + .hasArg(false) + .create('Z')); + + if(hasFilterOption()) + options.addOption(OptionBuilder.withLongOpt("filter") + .withDescription("filter, e.g. exact-subject=hello; matching-subject=%.a.#") + .hasArg(true) + .withArgName("=") + .create('F')); + + + if(hasTxnOption()) + { + options.addOption("x","txn",false,"use transactions"); + options.addOption(OptionBuilder.withLongOpt("batch-size") + .withDescription( "transaction batch size (default: 1)" ) + .hasArg(true) + .withArgName("BATCH-SIZE") + .create('B')); + options.addOption(OptionBuilder.withLongOpt("rollback-ratio") + .withDescription( "rollback ratio - must be between 0 and 1 (default: 0)" ) + .hasArg(true) + .withArgName("RATIO") + .create('R')); + } + + if(hasLinkDurableOption()) + { + options.addOption("d","durable-link",false,"use a durable link"); + } + + if(hasStdInOption()) + options.addOption("i","stdin",false,"read messages from stdin (one message per line)"); + + options.addOption(OptionBuilder.withLongOpt("trace") + .withDescription("trace logging specified categories: RAW, FRM") + .hasArg(true) + .withArgName("TRACE") + .create('t')); + if(hasSizeOption()) + options.addOption(OptionBuilder.withLongOpt("message-size") + .withDescription( "size to pad outgoing messages to" ) + .hasArg(true) + .withArgName("SIZE") + .create('z')); + + if(hasResponseQueueOption()) + options.addOption(OptionBuilder.withLongOpt("response-queue") + .withDescription( "response queue to reply to" ) + .hasArg(true) + .withArgName("RESPONSE_QUEUE") + .create('r')); + + if(hasLinkNameOption()) + { + options.addOption(OptionBuilder.withLongOpt("link") + .withDescription( "link name" ) + .hasArg(true) + .withArgName("LINK") + .create('l')); + } + + if(hasWindowSizeOption()) + { + options.addOption(OptionBuilder.withLongOpt("window-size") + .withDescription("credit window size") + .hasArg(true) + .withArgName("WINDOW-SIZE") + .create('W')); + } + + CommandLine cmdLine = null; + try + { + cmdLine = cmdLineParse.parse(options, args); + + } + catch (ParseException e) + { + printUsage(options); + System.exit(-1); + } + + if(cmdLine.hasOption('h') || cmdLine.getArgList().isEmpty()) + { + printUsage(options); + System.exit(0); + } + _host = cmdLine.getOptionValue('H',"0.0.0.0"); + _remoteHost = cmdLine.getOptionValue('O',null); + String portStr = cmdLine.getOptionValue('p',"5672"); + String countStr = cmdLine.getOptionValue('c',"1"); + + _useSSL = cmdLine.hasOption('S'); + + if(hasWindowSizeOption()) + { + String windowSizeStr = cmdLine.getOptionValue('W',"100"); + _windowSize = Integer.parseInt(windowSizeStr); + } + + if(hasSubjectOption()) + { + _subject = cmdLine.getOptionValue('s'); + } + + if(cmdLine.hasOption('u')) + { + _username = cmdLine.getOptionValue('u'); + } + + if(cmdLine.hasOption('w')) + { + _password = cmdLine.getOptionValue('w'); + } + + if(cmdLine.hasOption('F')) + { + _filter = cmdLine.getOptionValue('F'); + } + + _port = Integer.parseInt(portStr); + + _containerName = cmdLine.getOptionValue('C'); + + if(hasBlockOption()) + _block = cmdLine.hasOption('b'); + + if(hasLinkNameOption()) + _linkName = cmdLine.getOptionValue('l'); + + + if(hasLinkDurableOption()) + _durableLink = cmdLine.hasOption('d'); + + if(hasCountOption()) + _count = Integer.parseInt(countStr); + + if(hasStdInOption()) + _useStdIn = cmdLine.hasOption('i'); + + if(hasSingleLinkPerConnectionMode()) + _useMultipleConnections = cmdLine.hasOption('Z'); + + if(hasTxnOption()) + { + _useTran = cmdLine.hasOption('x'); + _batchSize = Integer.parseInt(cmdLine.getOptionValue('B',"1")); + _rollbackRatio = Double.parseDouble(cmdLine.getOptionValue('R',"0")); + } + + if(hasModeOption()) + { + _mode = AcknowledgeMode.ALO; + + if(cmdLine.hasOption('k')) + { + _mode = AcknowledgeMode.valueOf(cmdLine.getOptionValue('k')); + } + } + + if(hasResponseQueueOption()) + { + _responseQueue = cmdLine.getOptionValue('r'); + } + + _frameSize = Integer.parseInt(cmdLine.getOptionValue('f',"65536")); + + if(hasSizeOption()) + { + _messageSize = Integer.parseInt(cmdLine.getOptionValue('z',"-1")); + } + + String categoriesList = cmdLine.getOptionValue('t'); + String[]categories = categoriesList == null ? new String[0] : categoriesList.split("[, ]"); + for(String cat : categories) + { + if(cat.equalsIgnoreCase("FRM")) + { + FRAME_LOGGER.setLevel(Level.FINE); + Formatter formatter = new Formatter() + { + @Override + public String format(final LogRecord record) + { + return "[" + record.getMillis() + " FRM]\t" + record.getMessage() + "\n"; + } + }; + for(Handler handler : FRAME_LOGGER.getHandlers()) + { + FRAME_LOGGER.removeHandler(handler); + } + Handler handler = new ConsoleHandler(); + handler.setLevel(Level.FINE); + handler.setFormatter(formatter); + FRAME_LOGGER.addHandler(handler); + } + else if (cat.equalsIgnoreCase("RAW")) + { + RAW_LOGGER.setLevel(Level.FINE); + Formatter formatter = new Formatter() + { + @Override + public String format(final LogRecord record) + { + return "[" + record.getMillis() + " RAW]\t" + record.getMessage() + "\n"; + } + }; + for(Handler handler : RAW_LOGGER.getHandlers()) + { + RAW_LOGGER.removeHandler(handler); + } + Handler handler = new ConsoleHandler(); + handler.setLevel(Level.FINE); + handler.setFormatter(formatter); + RAW_LOGGER.addHandler(handler); + } + } + + + _args = cmdLine.getArgs(); + + } + + protected boolean hasFilterOption() + { + return false; + } + + protected boolean hasSubjectOption() + { + return false; + } + + protected boolean hasWindowSizeOption() + { + return false; + } + + protected boolean hasSingleLinkPerConnectionMode() + { + return false; + } + + protected abstract boolean hasLinkDurableOption(); + + protected abstract boolean hasLinkNameOption(); + + protected abstract boolean hasResponseQueueOption(); + + protected abstract boolean hasSizeOption(); + + protected abstract boolean hasBlockOption(); + + protected abstract boolean hasStdInOption(); + + protected abstract boolean hasTxnOption(); + + protected abstract boolean hasModeOption(); + + protected abstract boolean hasCountOption(); + + public String getHost() + { + return _host; + } + + public String getUsername() + { + return _username; + } + + public String getPassword() + { + return _password; + } + + public int getPort() + { + return _port; + } + + public int getCount() + { + return _count; + } + + public boolean useStdIn() + { + return _useStdIn; + } + + public boolean useTran() + { + return _useTran; + } + + public AcknowledgeMode getMode() + { + return _mode; + } + + public boolean isBlock() + { + return _block; + } + + public String[] getArgs() + { + return _args; + } + + public int getMessageSize() + { + return _messageSize; + } + + public String getResponseQueue() + { + return _responseQueue; + } + + public int getBatchSize() + { + return _batchSize; + } + + public double getRollbackRatio() + { + return _rollbackRatio; + } + + public String getLinkName() + { + return _linkName; + } + + public boolean isDurableLink() + { + return _durableLink; + } + + public boolean isUseMultipleConnections() + { + return _useMultipleConnections; + } + + public void setUseMultipleConnections(boolean useMultipleConnections) + { + _useMultipleConnections = useMultipleConnections; + } + + public String getSubject() + { + return _subject; + } + + public void setSubject(String subject) + { + _subject = subject; + } + + protected abstract void printUsage(final Options options); + + protected abstract void run(); + + + public Connection newConnection() throws Connection.ConnectionException + { + Container container = getContainerName() == null ? new Container() : new Container(getContainerName()); + return getUsername() == null ? new Connection(getHost(), getPort(), null, null, _frameSize, container, + _remoteHost == null ? getHost() : _remoteHost, _useSSL) + : new Connection(getHost(), getPort(), getUsername(), getPassword(), _frameSize, + container, _remoteHost == null ? getHost() : _remoteHost, _useSSL); + } + + public String getContainerName() + { + return _containerName; + } + + public int getWindowSize() + { + return _windowSize; + } + + public void setWindowSize(int windowSize) + { + _windowSize = windowSize; + } + + public String getFilter() + { + return _filter; + } +} diff --git a/java/amqp-1-0-common/build.xml b/java/amqp-1-0-common/build.xml new file mode 100644 index 0000000000..20b8b731b0 --- /dev/null +++ b/java/amqp-1-0-common/build.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractDescribedTypeWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractDescribedTypeWriter.java new file mode 100644 index 0000000000..6977a40902 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractDescribedTypeWriter.java @@ -0,0 +1,188 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class AbstractDescribedTypeWriter implements ValueWriter +{ + private int _length; + private Registry _registry; + private static final int LARGE_COMPOUND_THRESHOLD_COUNT = 10; + private ValueWriter _delegate; + private static final byte DESCRIBED_TYPE = (byte)0; + + public AbstractDescribedTypeWriter(final Registry registry) + { + _registry = registry; + } + + enum State { + FORMAT_CODE, + DESCRIPTOR, + DESCRIBED, + DONE + } + + private State _state = State.FORMAT_CODE; + + public int writeToBuffer(ByteBuffer buffer) + { + final int length = _length; + + if(length == -1) + { + writeFirstPass(buffer); + } + else + { + + State state = _state; + + switch(state) + { + case FORMAT_CODE: + if(buffer.hasRemaining()) + { + buffer.put(DESCRIBED_TYPE); + state = State.DESCRIPTOR; + _delegate = createDescriptorWriter(); + } + else + { + break; + } + + case DESCRIPTOR: + if(buffer.hasRemaining()) + { + _delegate.writeToBuffer(buffer); + if(_delegate.isComplete()) + { + state = State.DESCRIBED; + _delegate = createDescribedWriter(); + } + else + { + break; + } + } + case DESCRIBED: + if(buffer.hasRemaining()) + { + _delegate.writeToBuffer(buffer); + if(_delegate.isComplete()) + { + state = State.DONE; + _delegate = null; + } + else + { + break; + } + } + + } + + _state = state; + + } + + return _length; + } + + private void writeFirstPass(ByteBuffer buffer) + { + + int length = 1; + State state = State.FORMAT_CODE; + + ValueWriter descriptorWriter = createDescriptorWriter(); + if(buffer.hasRemaining()) + { + buffer.put(DESCRIBED_TYPE); + state = State.DESCRIPTOR; + _delegate = descriptorWriter; + } + length += descriptorWriter.writeToBuffer(buffer); + + ValueWriter describedWriter = createDescribedWriter(); + + if(descriptorWriter.isComplete()) + { + state = State.DESCRIBED; + _delegate = describedWriter; + } + + length += describedWriter.writeToBuffer(buffer); + + if(describedWriter.isComplete()) + { + _delegate = null; + state = State.DONE; + } + + _state = state; + _length = length; + } + + public void setValue(V value) + { + _length = -1; + _delegate = null; + _state = State.FORMAT_CODE; + onSetValue(value); + } + + public void setRegistry(Registry registry) + { + _registry = registry; + } + + protected Registry getRegistry() + { + return _registry; + } + + protected abstract void onSetValue(final V value); + + protected abstract void clear(); + + protected abstract ValueWriter createDescribedWriter(); + + protected abstract Object getDescriptor(); + + protected final ValueWriter createDescriptorWriter() + { + return getRegistry().getValueWriter(getDescriptor()); + } + + public boolean isComplete() + { + return _state == State.DONE; + } + + public boolean isCacheable() + { + return false; + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractListWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractListWriter.java new file mode 100644 index 0000000000..655b1f2164 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractListWriter.java @@ -0,0 +1,41 @@ +/* + * + * 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.amqp_1_0.codec; + +public abstract class AbstractListWriter extends CompoundWriter +{ + public AbstractListWriter(final Registry registry) + { + super(registry); + } + + @Override + protected byte getFourOctetEncodingCode() + { + return (byte)0xd0; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return (byte)0xc0; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractMapWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractMapWriter.java new file mode 100644 index 0000000000..0fa29b5210 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractMapWriter.java @@ -0,0 +1,95 @@ +/* + * + * 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.amqp_1_0.codec; + +public abstract class AbstractMapWriter extends CompoundWriter +{ + private boolean onKey; + + public AbstractMapWriter(Registry registry) + { + super(registry); + } + + @Override + protected byte getFourOctetEncodingCode() + { + return (byte)0xd1; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return (byte)0xc1; + } + + @Override + protected final int getCount() + { + return 2 * getMapCount(); + } + + protected abstract int getMapCount(); + + @Override + protected final boolean hasNext() + { + return onKey || hasMapNext(); + } + + protected abstract boolean hasMapNext(); + + @Override + protected final Object next() + { + if(onKey = !onKey) + { + return nextKey(); + } + else + { + return nextValue(); + } + } + + protected abstract Object nextValue(); + + protected abstract Object nextKey(); + + @Override + protected final void clear() + { + onKey = false; + onClear(); + } + + protected abstract void onClear(); + + @Override + protected final void reset() + { + onKey = false; + onReset(); + } + + protected abstract void onReset(); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayTypeConstructor.java new file mode 100644 index 0000000000..68239ad143 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayTypeConstructor.java @@ -0,0 +1,113 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.AmqpError; + +import java.lang.reflect.Array; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public abstract class ArrayTypeConstructor implements TypeConstructor +{ + + + + public Object[] construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + int size = read(in); + if(in.remaining() < size) + { + throw new AmqpErrorException(AmqpError.DECODE_ERROR, + "Insufficient data to decode array - requires %d octects, only %d remaining.", + size, in.remaining()); + } + ByteBuffer dup = in.slice(); + dup.limit(size); + in.position(in.position()+size); + int count = read(dup); + TypeConstructor t = handler.readConstructor(dup); + List rval = new ArrayList(count); + for(int i = 0; i < count; i++) + { + rval.add(t.construct(dup, handler)); + } + if(dup.hasRemaining()) + { + throw new AmqpErrorException(AmqpError.DECODE_ERROR, + "Array incorrectly encoded, %d bytes remaining after decoding %d elements", + dup.remaining(), count); + } + if(rval.size() == 0) + { + return null; + } + else + { + + + return rval.toArray((Object[])Array.newInstance(rval.get(0).getClass(), rval.size())); + } + } + + + abstract int read(ByteBuffer in) throws AmqpErrorException; + + + private static final ArrayTypeConstructor ONE_BYTE_SIZE_ARRAY = new ArrayTypeConstructor() + { + + @Override int read(final ByteBuffer in) throws AmqpErrorException + { + if(!in.hasRemaining()) + { + throw new AmqpErrorException(AmqpError.DECODE_ERROR, "Insufficient data to decode array"); + } + return ((int)in.get()) & 0xff; + } + + }; + + private static final ArrayTypeConstructor FOUR_BYTE_SIZE_ARRAY = new ArrayTypeConstructor() + { + + @Override int read(final ByteBuffer in) throws AmqpErrorException + { + if(in.remaining()<4) + { + throw new AmqpErrorException(AmqpError.DECODE_ERROR, "Insufficient data to decode array"); + } + return in.getInt(); + } + + }; + + public static ArrayTypeConstructor getOneByteSizeTypeConstructor() + { + return ONE_BYTE_SIZE_ARRAY; + } + + public static ArrayTypeConstructor getFourByteSizeTypeConstructor() + { + return FOUR_BYTE_SIZE_ARRAY; + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayWriter.java new file mode 100644 index 0000000000..7766a486f0 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayWriter.java @@ -0,0 +1,82 @@ +/* + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class ArrayWriter implements ValueWriter +{ + private Object[] _list; + private int _position = 0; + private final Registry _registry; + private ValueWriter valueWriter; + + public ArrayWriter(final Registry registry) + { + _registry = registry; + } + + + protected void onSetValue(final Object[] value) + { + + Class clazz = value.getClass().getComponentType(); + //valueWriter = _registry.getValueWriterByClass(clazz); + + + } + + + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ArrayWriter(registry); + } + }; + + public static void register(Registry registry) + { + //registry.register(List.class, FACTORY); + } + + public int writeToBuffer(final ByteBuffer buffer) + { + return 0; //TODO change body of implemented methods use File | Settings | File Templates. + } + + public void setValue(final Object[] frameBody) + { + //TODO change body of implemented methods use File | Settings | File Templates. + } + + public boolean isComplete() + { + return false; //TODO change body of implemented methods use File | Settings | File Templates. + } + + public boolean isCacheable() + { + return false; //TODO change body of implemented methods use File | Settings | File Templates. + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryString.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryString.java new file mode 100644 index 0000000000..76bdac8ed7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryString.java @@ -0,0 +1,68 @@ +package org.apache.qpid.amqp_1_0.codec; + + +final class BinaryString +{ + + private byte[] _data; + private int _offset; + private int _size; + private int _hashCode; + + BinaryString(final byte[] data, final int offset, final int size) + { + + setData(data, offset, size); + } + + BinaryString() + { + } + + void setData(byte[] data, int offset, int size) + { + _data = data; + _offset = offset; + _size = size; + int hc = 0; + for (int i = 0; i < size; i++) + { + hc = 31*hc + (0xFF & data[offset + i]); + } + _hashCode = hc; + } + + + public final int hashCode() + { + return _hashCode; + } + + public final boolean equals(Object o) + { + BinaryString buf = (BinaryString) o; + final int size = _size; + if (size != buf._size) + { + return false; + } + + final byte[] myData = _data; + final byte[] theirData = buf._data; + int myOffset = _offset; + int theirOffset = buf._offset; + final int myLimit = myOffset + size; + + while(myOffset < myLimit) + { + if (myData[myOffset++] != theirData[theirOffset++]) + { + return false; + } + } + + return true; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryTypeConstructor.java new file mode 100644 index 0000000000..e83718d88d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryTypeConstructor.java @@ -0,0 +1,80 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Binary; + +import java.nio.ByteBuffer; + +public class BinaryTypeConstructor extends VariableWidthTypeConstructor +{ + private static final BinaryTypeConstructor INSTANCE_1 = new BinaryTypeConstructor(1); + private static final BinaryTypeConstructor INSTANCE_4 = new BinaryTypeConstructor(4); + + public static BinaryTypeConstructor getInstance(int i) + { + return i == 1 ? INSTANCE_1 : INSTANCE_4; + } + + + private BinaryTypeConstructor(int size) + { + super(size); + } + + @Override + public Object construct(final ByteBuffer in, boolean isCopy, ValueHandler handler) throws AmqpErrorException + { + int size; + + if(getSize() == 1) + { + size = in.get() & 0xFF; + } + else + { + size = in.getInt(); + } + + ByteBuffer inDup = in.slice(); + inDup.limit(inDup.position()+size); + + Binary binary; +/* if(isCopy && inDup.hasArray()) + { + binary= new Binary(inDup.array(), inDup.arrayOffset()+inDup.position(),size); + } + else + {*/ + byte[] buf = new byte[size]; + inDup.get(buf); + binary = new Binary(buf); + /* }*/ + + in.position(in.position()+size); + + + return binary; + + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryWriter.java new file mode 100644 index 0000000000..8ab4569646 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryWriter.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.Binary; + +public class BinaryWriter extends SimpleVariableWidthWriter +{ + private int _offset; + private int _length; + + @Override + protected byte getFourOctetEncodingCode() + { + return (byte)0xb0; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return (byte)0xa0; + } + + @Override + protected byte[] getByteArray(Binary value) + { + _offset = value.getArrayOffset(); + _length = value.getLength(); + return value.getArray(); + } + + @Override + protected int getOffset() + { + return _offset; + } + + @Override protected int getLength() + { + return _length; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new BinaryWriter(); + } + }; + + public static void register(Registry registry) + { + registry.register(Binary.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanConstructor.java new file mode 100644 index 0000000000..5cad87cbd8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanConstructor.java @@ -0,0 +1,80 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class BooleanConstructor +{ + private static final TypeConstructor TRUE_INSTANCE = new TypeConstructor() + { + public Boolean construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return Boolean.TRUE; + } + }; + + private static final TypeConstructor FALSE_INSTANCE = new TypeConstructor() + { + public Boolean construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return Boolean.FALSE; + } + }; + private static final TypeConstructor BYTE_INSTANCE = new TypeConstructor() + { + public Boolean construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + byte b = in.get(); + return b != (byte) 0; + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct boolean: insufficient input data"); + throw new AmqpErrorException(error); + } + } + + }; + + + public static TypeConstructor getTrueInstance() + { + return TRUE_INSTANCE; + } + + public static TypeConstructor getFalseInstance() + { + return FALSE_INSTANCE; + } + + public static TypeConstructor getByteInstance() + { + return BYTE_INSTANCE; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanWriter.java new file mode 100644 index 0000000000..fb4449fb2c --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanWriter.java @@ -0,0 +1,70 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class BooleanWriter implements ValueWriter +{ + private boolean _complete = true; + private boolean _value; + + public int writeToBuffer(ByteBuffer buffer) + { + if(!_complete & buffer.hasRemaining()) + { + buffer.put(_value ? (byte)0x41 : (byte)0x42); + _complete = true; + } + return 1; + } + + public void setValue(Boolean value) + { + _complete = false; + _value = value.booleanValue(); + } + + public boolean isCacheable() + { + return true; + } + + public boolean isComplete() + { + return _complete; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new BooleanWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Boolean.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteArrayWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteArrayWriter.java new file mode 100644 index 0000000000..662b4085db --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteArrayWriter.java @@ -0,0 +1,66 @@ +/* + * + * 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.amqp_1_0.codec; + +public class ByteArrayWriter extends SimpleVariableWidthWriter +{ + + @Override + protected byte getFourOctetEncodingCode() + { + return (byte)0xb0; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return (byte)0xa0; + } + + @Override + protected byte[] getByteArray(byte[] value) + { + return value; + } + + + @Override + protected int getOffset() + { + return 0; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ByteArrayWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(byte[].class, FACTORY); + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteBufferWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteBufferWriter.java new file mode 100644 index 0000000000..41bd20c0a2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteBufferWriter.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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class ByteBufferWriter extends SimpleVariableWidthWriter +{ + + @Override + protected byte getFourOctetEncodingCode() + { + return (byte)0xb0; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return (byte)0xa0; + } + + @Override + protected byte[] getByteArray(ByteBuffer value) + { + if(value.hasArray() && value.arrayOffset() == 0 && value.remaining() == value.array().length) + { + return value.array(); + } + else + { + byte[] copy = new byte[value.remaining()]; + value.duplicate().get(copy); + return copy; + } + } + + @Override + protected int getOffset() + { + return 0; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ByteBufferWriter(); + } + }; + + public static void register(Registry registry) + { + registry.register(ByteBuffer.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteTypeConstructor.java new file mode 100644 index 0000000000..03db2c568c --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteTypeConstructor.java @@ -0,0 +1,59 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class ByteTypeConstructor implements TypeConstructor +{ + private static final ByteTypeConstructor INSTANCE = new ByteTypeConstructor(); + + public static ByteTypeConstructor getInstance() + { + return INSTANCE; + } + + private ByteTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + return in.get(); + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct byte: insufficient input data"); + throw new AmqpErrorException(error); + + } + + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteWriter.java new file mode 100644 index 0000000000..6155de4d2a --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteWriter.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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class ByteWriter implements ValueWriter +{ + private int _written = 2; + private byte _value; + + public int writeToBuffer(ByteBuffer buffer) + { + + switch(_written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put((byte)0x51); + } + else + { + break; + } + case 1: + if(buffer.hasRemaining()) + { + buffer.put(_value); + _written = 2; + } + else + { + _written = 1; + } + + } + + return 2; + } + + public void setValue(Byte value) + { + _written = 0; + _value = value.byteValue(); + } + + public boolean isComplete() + { + return _written == 2; + } + + public boolean isCacheable() + { + return true; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ByteWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Byte.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharTypeConstructor.java new file mode 100644 index 0000000000..6a2ce2d725 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharTypeConstructor.java @@ -0,0 +1,67 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.*; + +import java.nio.ByteBuffer; + +public class CharTypeConstructor implements TypeConstructor +{ + private static final CharTypeConstructor INSTANCE = new CharTypeConstructor(); + + + public static CharTypeConstructor getInstance() + { + return INSTANCE; + } + + private CharTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=4) + { + int codePoint = in.getInt(); + char[] chars = Character.toChars(codePoint); + if(chars.length == 1) + { + return chars[0]; + } + else + { + return chars; + } + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct char: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharWriter.java new file mode 100644 index 0000000000..05f6e28d2f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharWriter.java @@ -0,0 +1,53 @@ +/* + * + * 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.amqp_1_0.codec; + +public class CharWriter extends FixedFourWriter +{ + private static final byte FORMAT_CODE = (byte)0x73; + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + @Override + int convertValueToInt(Character value) + { + return (int) value.charValue(); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new CharWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Character.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeAssembler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeAssembler.java new file mode 100644 index 0000000000..5625797f74 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeAssembler.java @@ -0,0 +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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +public interface CompoundTypeAssembler +{ + + public static interface Factory + { + CompoundTypeAssembler newInstance(); + } + + void init(int count) throws AmqpErrorException; + void addItem(Object obj) throws AmqpErrorException; + Object complete() throws AmqpErrorException; +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeConstructor.java new file mode 100644 index 0000000000..fc4fcdf9ee --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeConstructor.java @@ -0,0 +1,192 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CompoundTypeConstructor extends VariableWidthTypeConstructor +{ + private final CompoundTypeAssembler.Factory _assemblerFactory; + + public static final CompoundTypeAssembler.Factory LIST_ASSEMBLER_FACTORY = + new CompoundTypeAssembler.Factory() + { + + public CompoundTypeAssembler newInstance() + { + return new ListAssembler(); + } + }; + + + + private static class ListAssembler implements CompoundTypeAssembler + { + private List _list; + + public void init(final int count) throws AmqpErrorException + { + _list = new ArrayList(count); + } + + public void addItem(final Object obj) throws AmqpErrorException + { + _list.add(obj); + } + + public Object complete() throws AmqpErrorException + { + return _list; + } + + @Override + public String toString() + { + return "ListAssembler{" + + "_list=" + _list + + '}'; + } + } + + + public static final CompoundTypeAssembler.Factory MAP_ASSEMBLER_FACTORY = + new CompoundTypeAssembler.Factory() + { + + public CompoundTypeAssembler newInstance() + { + return new MapAssembler(); + } + }; + + private static class MapAssembler implements CompoundTypeAssembler + { + private Map _map; + private Object _lastKey; + private static final Object NOT_A_KEY = new Object(); + + + public void init(final int count) throws AmqpErrorException + { + // Can't have an odd number of elements in a map + if((count & 0x1) == 1) + { + Error error = new Error(); + error.setCondition(AmqpError.DECODE_ERROR); + Formatter formatter = new Formatter(); + formatter.format("map cannot have odd number of elements: %d", count); + error.setDescription(formatter.toString()); + throw new AmqpErrorException(error); + } + _map = new HashMap(count); + _lastKey = NOT_A_KEY; + } + + public void addItem(final Object obj) throws AmqpErrorException + { + if(_lastKey != NOT_A_KEY) + { + if(_map.put(_lastKey, obj) != null) + { + Error error = new Error(); + error.setCondition(AmqpError.DECODE_ERROR); + Formatter formatter = new Formatter(); + formatter.format("map cannot have duplicate keys: %s has values (%s, %s)", _lastKey, _map.get(_lastKey), obj); + error.setDescription(formatter.toString()); + + throw new AmqpErrorException(error); + } + _lastKey = NOT_A_KEY; + } + else + { + _lastKey = obj; + } + + } + + public Object complete() throws AmqpErrorException + { + return _map; + } + } + + + public static CompoundTypeConstructor getInstance(int i, + CompoundTypeAssembler.Factory assemblerFactory) + { + return new CompoundTypeConstructor(i, assemblerFactory); + } + + + private CompoundTypeConstructor(int size, + final CompoundTypeAssembler.Factory assemblerFactory) + { + super(size); + _assemblerFactory = assemblerFactory; + } + + @Override + public Object construct(final ByteBuffer in, boolean isCopy, ValueHandler delegate) throws AmqpErrorException + { + int size; + int count; + + if(getSize() == 1) + { + size = in.get() & 0xFF; + count = in.get() & 0xFF; + } + else + { + size = in.getInt(); + count = in.getInt(); + } + + ByteBuffer data; + ByteBuffer inDup = in.slice(); + + inDup.limit(size-getSize()); + + CompoundTypeAssembler assembler = _assemblerFactory.newInstance(); + + assembler.init(count); + + for(int i = 0; i < count; i++) + { + assembler.addItem(delegate.parse(in)); + } + + return assembler.complete(); + + } + + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundWriter.java new file mode 100644 index 0000000000..39dce2b448 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundWriter.java @@ -0,0 +1,420 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +public abstract class CompoundWriter implements ValueWriter +{ + private int _length; + private Registry _registry; + private static final int LARGE_COMPOUND_THRESHOLD_COUNT = 25; + private ValueWriter _delegate; + private Map _writerCache = new HashMap(); + + public CompoundWriter(final Registry registry) + { + _registry = registry; + } + + enum State { + FORMAT_CODE, + SIZE_0, + SIZE_1, + SIZE_2, + SIZE_3, + COUNT_0, + COUNT_1, + COUNT_2, + COUNT_3, + DELEGATING, + DONE + } + + private State _state = State.FORMAT_CODE; + + public int writeToBuffer(ByteBuffer buffer) + { + return writeToBuffer(buffer, false); + } + + public int writeToBuffer(ByteBuffer buffer, boolean large) + { + final int length = _length; + + if(length == -1) + { + writeFirstPass(buffer, (large || getCount() > LARGE_COMPOUND_THRESHOLD_COUNT) ? 4 : 1); + if(_delegate != null && _delegate.isComplete()) + { + _delegate = null; + } + } + else + { + // + + final int size = (length & 0xFFFFFF00) == 0 ? 1 : 4; + final int count = getCount(); + final int typeLength = length - (1+size); + + State state = _state; + + switch(state) + { + case FORMAT_CODE: + if(buffer.hasRemaining()) + { + buffer.put(size == 1 ? getSingleOctetEncodingCode(): getFourOctetEncodingCode()); + state = State.SIZE_0; + } + else + { + break; + } + + case SIZE_0: + if(size == 4) + { + if(buffer.remaining()>=4) + { + buffer.putInt(typeLength); + state = State.COUNT_0; + } + } + else if(size == 1) + { + if(buffer.hasRemaining()) + { + buffer.put((byte)(typeLength)); + state = State.COUNT_0; + } + else + { + break; + } + + } + case SIZE_1: + case SIZE_2: + if(state != State.COUNT_0 && buffer.remaining() >= 2) + { + buffer.putShort((short)(((typeLength) >> ((3-state.ordinal())<<3)) & 0xFFFF )); + state = (state == State.SIZE_0) + ? State.SIZE_2 + : (state == State.SIZE_1) + ? State.SIZE_3 + : State.COUNT_0; + } + case SIZE_3: + if(state != State.COUNT_0 && buffer.hasRemaining()) + { + buffer.put((byte)(((typeLength) >> ((4-state.ordinal())<<3)) & 0xFF )); + state = (state == State.SIZE_0) + ? State.SIZE_1 + : (state == State.SIZE_1) + ? State.SIZE_2 + : (state == State.SIZE_2) + ? State.SIZE_3 + : State.COUNT_0; + } + case COUNT_0: + if(size == 4) + { + if(buffer.remaining()>=4) + { + buffer.putInt(count); + state = State.DELEGATING; + } + } + else if(size == 1) + { + if(buffer.hasRemaining()) + { + buffer.put((byte)count); + state = State.DELEGATING; + } + else + { + break; + } + + } + + case COUNT_1: + case COUNT_2: + if(state != State.DELEGATING && buffer.remaining() >= 2) + { + buffer.putShort((short)((count >> ((7-state.ordinal())<<3)) & 0xFFFF )); + state = state == State.COUNT_0 + ? State.COUNT_2 + : state == State.COUNT_1 + ? State.COUNT_3 + : State.DELEGATING; + } + case COUNT_3: + if(state != State.DELEGATING && buffer.hasRemaining()) + { + buffer.put((byte)((count >> ((8-state.ordinal())<<3)) & 0xFF )); + state = state == State.COUNT_0 + ? State.COUNT_1 + : state == State.COUNT_1 + ? State.COUNT_2 + : state == State.COUNT_2 + ? State.COUNT_3 + : State.DELEGATING; + } + case DELEGATING: + while(state == State.DELEGATING && buffer.hasRemaining()) + { + if(_delegate == null || _delegate.isComplete()) + { + if(hasNext()) + { + Object val = next(); + _delegate = _registry.getValueWriter(val); + } + else + { + state = State.DONE; + break; + } + } + _delegate.writeToBuffer(buffer); + } + } + + _state = state; + + } + + return _length; + } + + private void writeFirstPass(ByteBuffer buffer, int size) + { + + State state = State.FORMAT_CODE; + /*ByteBuffer origBuffer = buffer; + buffer = buffer.duplicate();*/ + int origPosition = buffer.position(); + int length ; + + + if(size == 4) + { + if(buffer.hasRemaining()) + { + buffer.put(getFourOctetEncodingCode()); + + // Skip the size - we will come back and patch this + if(buffer.remaining() >= 4 ) + { + buffer.position(buffer.position()+4); + state = State.COUNT_0; + } + else + { + state = State.values()[buffer.remaining()+1]; + buffer.position(buffer.limit()); + } + + + switch(buffer.remaining()) + { + case 0: + break; + case 1: + buffer.put((byte)((getCount() >> 24) & 0xFF)); + state = State.COUNT_1; + break; + case 2: + buffer.putShort((short)((getCount() >> 16) & 0xFFFF)); + state = State.COUNT_2; + break; + case 3: + buffer.putShort((short)((getCount() >> 16) & 0xFFFF)); + buffer.put((byte)((getCount() >> 8) & 0xFF)); + state = State.COUNT_3; + break; + default: + buffer.putInt(getCount()); + state = State.DELEGATING; + } + + + + } + length = 9; + + + + } + else + { + if(buffer.hasRemaining()) + { + buffer.put(getSingleOctetEncodingCode()); + if(buffer.hasRemaining()) + { + // Size - we will come back and patch this + buffer.put((byte) 0); + + if(buffer.hasRemaining()) + { + buffer.put((byte)getCount()); + state = State.DELEGATING; + } + else + { + state = State.COUNT_0; + } + } + else + { + state = State.SIZE_0; + } + } + length = 3; + + } + + + int iterPos = -1; + for(int i = 0; i < getCount(); i++) + { + Object val = next(); + ValueWriter writer = _registry.getValueWriter(val, _writerCache); + if(writer == null) + { + // TODO + System.out.println("no writer for " + val); + } + length += writer.writeToBuffer(buffer); + if(iterPos == -1 && !writer.isComplete()) + { + iterPos = i; + _delegate = writer; + } + + if(size == 1 && length > 255) + { + reset(); + buffer.position(origPosition); + writeFirstPass(buffer, 4); + return; + } + + } + + // TODO - back-patch size + if(buffer.limit() - origPosition >= 2) + { + buffer.position(origPosition+1); + if(size == 1) + { + buffer.put((byte)((length & 0xFF)-2)); + } + else + { + switch(buffer.remaining()) + { + case 1: + buffer.put((byte)(((length-5) >> 24) & 0xFF)); + break; + case 2: + buffer.putShort((short)(((length-5) >> 16) & 0xFFFF)); + break; + case 3: + buffer.putShort((short)(((length-5) >> 16) & 0xFFFF)); + buffer.put((byte)(((length-5) >> 8) & 0xFF)); + break; + default: + buffer.putInt(length-5); + } + } + } + + if(buffer.limit() - origPosition >= length) + { + buffer.position(origPosition+length); + state = State.DONE; + } + else + { + reset(); + while(iterPos-- >= 0) + { + next(); + } + buffer.position(buffer.limit()); + } + _state = state; + _length = length; + } + + protected abstract byte getFourOctetEncodingCode(); + + protected abstract byte getSingleOctetEncodingCode(); + + public void setValue(V value) + { + _length = -1; + _delegate = null; + _state = State.FORMAT_CODE; + onSetValue(value); + } + + public void setRegistry(Registry registry) + { + _registry = registry; + } + + public Registry getRegistry() + { + return _registry; + } + + protected abstract void onSetValue(final V value); + + protected abstract int getCount(); + + protected abstract boolean hasNext(); + + protected abstract Object next(); + + protected abstract void clear(); + + protected abstract void reset(); + + public boolean isCacheable() + { + return false; + } + + public boolean isComplete() + { + return _state == State.DONE; + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DecimalConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DecimalConstructor.java new file mode 100644 index 0000000000..6c3b64aa25 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DecimalConstructor.java @@ -0,0 +1,230 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.math.BigDecimal; +import java.nio.ByteBuffer; + +public abstract class DecimalConstructor implements TypeConstructor +{ + + private static final DecimalConstructor DECIMAL_32 = new DecimalConstructor() + { + + public BigDecimal construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + + + int val; + + if(in.remaining()>=4) + { + val = in.getInt(); + } + else + { + throw new AmqpErrorException(ConnectionError.FRAMING_ERROR, "Cannot construct decimal32: insufficient input data"); + } + + return constructFrom32(val);} + + }; + + + private static final DecimalConstructor DECIMAL_64 = new DecimalConstructor() + { + + public BigDecimal construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + long val; + + if(in.remaining()>=8) + { + val = in.getLong(); + } + else + { + throw new AmqpErrorException(ConnectionError.FRAMING_ERROR, "Cannot construct decimal64: insufficient input data"); + } + + return constructFrom64(val); + + } + + }; + + + private static final DecimalConstructor DECIMAL_128 = new DecimalConstructor() + { + + public BigDecimal construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + long high; + long low; + + if(in.remaining()>=16) + { + high = in.getLong(); + low = in.getLong(); + } + else + { + throw new AmqpErrorException(ConnectionError.FRAMING_ERROR, "Cannot construct decimal128: insufficient input data"); + } + + return constructFrom128(high, low); + + } + + }; + + private static final BigDecimal TWO_TO_THE_SIXTY_FOUR = new BigDecimal(2).pow(64); + + private static BigDecimal constructFrom128(long high, long low) + { + int sign = ((high & 0x8000000000000000l) == 0) ? 1 : -1; + + int exponent = 0; + long significand = high; + + if((high & 0x6000000000000000l) != 0x6000000000000000l) + { + exponent = ((int) ((high & 0x7FFE000000000000l) >> 49)) - 6176; + significand = high & 0x0001ffffffffffffl; + } + else if((high & 0x7800000000000000l) != 0x7800000000000000l) + { + exponent = ((int)((high & 0x1fff800000000000l)>>47)) - 6176; + significand = (0x00007fffffffffffl & high) | 0x0004000000000000l; + } + else + { + // NaN or infinite + return null; + } + + + BigDecimal bigDecimal = new BigDecimal(significand).multiply(TWO_TO_THE_SIXTY_FOUR); + if(low >=0) + { + bigDecimal = bigDecimal.add(new BigDecimal(low)); + } + else + { + bigDecimal = bigDecimal.add(TWO_TO_THE_SIXTY_FOUR.add(new BigDecimal(low))); + } + if(((high & 0x8000000000000000l) != 0)) + { + bigDecimal = bigDecimal.negate(); + } + bigDecimal = bigDecimal.scaleByPowerOfTen(exponent); + return bigDecimal; + } + + + private static BigDecimal constructFrom64(final long val) + { + int sign = ((val & 0x8000000000000000l) == 0) ? 1 : -1; + + int exponent = 0; + long significand = val; + + if((val & 0x6000000000000000l) != 0x6000000000000000l) + { + exponent = ((int) ((val & 0x7FE0000000000000l) >> 53)) - 398; + significand = val & 0x001fffffffffffffl; + } + else if((val & 0x7800000000000000l) != 0x7800000000000000l) + { + exponent = ((int)((val & 0x1ff8000000000000l)>>51)) - 398; + significand = (0x0007ffffffffffffl & val) | 0x0020000000000000l; + } + else + { + // NaN or infinite + return null; + } + + BigDecimal bigDecimal = new BigDecimal(sign * significand); + bigDecimal = bigDecimal.scaleByPowerOfTen(exponent); + return bigDecimal; + } + + private static BigDecimal constructFrom32(final int val) + { + int sign = ((val & 0x80000000) == 0) ? 1 : -1; + + int exponent = 0; + int significand = val; + + if((val & 0x60000000) != 0x60000000) + { + exponent = ((int) ((val & 0x7F800000) >> 23)) - 101; + significand = val & 0x007fffffff; + } + else if((val & 0x78000000) != 0x78000000) + { + exponent = ((int)((val & 0x1fe00000)>>21)) - 101; + significand = (0x001fffff & val) | 0x00800000; + } + else + { + // NaN or infinite + return null; + } + + BigDecimal bigDecimal = new BigDecimal(sign * significand); + bigDecimal = bigDecimal.scaleByPowerOfTen(exponent); + return bigDecimal; + } + +/* + + public static void main(String[] args) + { + System.out.println(constructFrom128(0l,0l)); + System.out.println(constructFrom128(0x3041ED09BEAD87C0l,0x378D8E63FFFFFFFFl)); + System.out.println(constructFrom64(0l)); + System.out.println(constructFrom64(0x5fe0000000000001l)); + System.out.println(constructFrom64(0xec7386F26FC0FFFFl)); + System.out.println(constructFrom32(0)); + System.out.println(constructFrom32(0x6cb8967f)); + + } +*/ + + public static TypeConstructor getDecimal32Instance() + { + return DECIMAL_32; + } + + public static TypeConstructor getDecimal64Instance() + { + return DECIMAL_64; + } + + public static TypeConstructor getDecimal128Instance() + { + return DECIMAL_128; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DefaultDescribedTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DefaultDescribedTypeConstructor.java new file mode 100644 index 0000000000..48b2045298 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DefaultDescribedTypeConstructor.java @@ -0,0 +1,70 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DefaultDescribedTypeConstructor extends DescribedTypeConstructor +{ + private Object _descriptor; + + public DefaultDescribedTypeConstructor(final Object descriptor) + { + _descriptor = descriptor; + } + + public Object construct(final Object underlying) + { + return new DescribedType(_descriptor, underlying); + } + + + public static void main(String[] args) throws IOException, ParseException + { + LineNumberReader reader = new LineNumberReader(new InputStreamReader(System.in)); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS"); + String line; + Pattern pattern = Pattern.compile("^\\d+ (\\d{4}-\\d{2}-\\d{2} \\d\\d:\\d\\d:\\d\\d,\\d\\d\\d)"); + + long prevTime = Long.MAX_VALUE; + + while((line = reader.readLine()) != null) + { + Matcher m = pattern.matcher(line); + if(m.matches()) + { + String timeStr = m.group(1); + long time = df.parse(timeStr).getTime(); + if(time - prevTime > 20000) + { + System.out.println(df.format(prevTime) + " - " + df.format(time)); + } + prevTime = time; + } + } + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DelegatingValueWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DelegatingValueWriter.java new file mode 100644 index 0000000000..b11530d94f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DelegatingValueWriter.java @@ -0,0 +1,52 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class DelegatingValueWriter implements ValueWriter +{ + private ValueWriter _delegate; + private Registry _registry; + + + protected DelegatingValueWriter(final Registry registry) + { + _registry = registry; + } + + public int writeToBuffer(final ByteBuffer buffer) + { + return _delegate.writeToBuffer(buffer); + } + + public void setValue(final V frameBody) + { + _delegate = _registry.getValueWriter(getUnderlyingValue(frameBody)); + } + + protected abstract Object getUnderlyingValue(final V frameBody); + + public boolean isComplete() + { + return _delegate.isComplete(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedType.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedType.java new file mode 100644 index 0000000000..2f171c49b2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedType.java @@ -0,0 +1,85 @@ +/* + * + * 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.amqp_1_0.codec; + +public class DescribedType +{ + private final Object _descriptor; + private final Object _described; + + public DescribedType(final Object descriptor, final Object described) + { + _descriptor = descriptor; + _described = described; + } + + public Object getDescriptor() + { + return _descriptor; + } + + public Object getDescribed() + { + return _described; + } + + @Override + public boolean equals(final Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + final DescribedType that = (DescribedType) o; + + if (_described != null ? !_described.equals(that._described) : that._described != null) + { + return false; + } + if (_descriptor != null ? !_descriptor.equals(that._descriptor) : that._descriptor != null) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = _descriptor != null ? _descriptor.hashCode() : 0; + result = 31 * result + (_described != null ? _described.hashCode() : 0); + return result; + } + + @Override + public String toString() + { + return "DescribedType{"+ _descriptor + + ", " + _described + + '}'; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructor.java new file mode 100644 index 0000000000..4093583441 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructor.java @@ -0,0 +1,41 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +import java.nio.ByteBuffer; + +public abstract class DescribedTypeConstructor +{ + public TypeConstructor construct(final TypeConstructor describedConstructor) throws AmqpErrorException + { + return new TypeConstructor() + { + public T construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return DescribedTypeConstructor.this.construct(describedConstructor.construct(in, handler)); + } + }; + } + + public abstract T construct(Object underlying); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructorRegistry.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructorRegistry.java new file mode 100644 index 0000000000..38cfa0f5a7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructorRegistry.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.amqp_1_0.codec; + +public interface DescribedTypeConstructorRegistry +{ + public static interface Source + { + public DescribedTypeConstructorRegistry getDescribedTypeRegistry(); + } + + void register(Object descriptor, DescribedTypeConstructor constructor); + + DescribedTypeConstructor getConstructor(Object descriptor); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleTypeConstructor.java new file mode 100644 index 0000000000..439ad73875 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleTypeConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class DoubleTypeConstructor implements TypeConstructor +{ + private static final DoubleTypeConstructor INSTANCE = new DoubleTypeConstructor(); + + + public static DoubleTypeConstructor getInstance() + { + return INSTANCE; + } + + private DoubleTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=8) + { + return in.getDouble(); + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct double: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleWriter.java new file mode 100644 index 0000000000..372e739a51 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleWriter.java @@ -0,0 +1,54 @@ +/* + * + * 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.amqp_1_0.codec; + +public class DoubleWriter extends FixedEightWriter +{ + private static final byte FORMAT_CODE = (byte) 0x82; + + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + @Override + long convertValueToLong(Double value) + { + return Double.doubleToLongBits(value.doubleValue()); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DoubleWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Double.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/Encoder.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/Encoder.java new file mode 100644 index 0000000000..9b2a654f10 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/Encoder.java @@ -0,0 +1,85 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedByte; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.UnsignedShort; + +import java.nio.ByteBuffer; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public interface Encoder +{ + + public boolean writeNull(); + + public boolean writeBoolean(boolean b); + + public boolean writeByte(byte b); + + public boolean writeUnsignedByte(ByteBuffer buf, UnsignedByte ub); + + public boolean writeShort(ByteBuffer buf, short s); + + public boolean writeUnsignedShort(UnsignedShort s); + + public boolean writeInt(int i); + + public boolean writeUnsignedInt(UnsignedInteger i); + + public boolean writeLong(long l); + + public boolean writeUnsignedLong(UnsignedLong l); + + public boolean writeFloat(float f); + + public boolean writeDouble(double d); + + public boolean writeChar(char c); + + public boolean writeTimestamp(Date d); + + public boolean writeSymbol(Symbol s); + + public boolean writeString(String s); + + public boolean writeBytes(byte[] bytes); + + public boolean writeBytes(Binary bin); + + public boolean writeList(List l); + + public boolean writeMap(Map m); + + public boolean writeEncodable(EncodableValue o); + + public boolean writeDescribedType(EncodableValue descriptor, EncodableValue described); + + interface EncodableValue + { + void encode(Encoder encoder); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedEightWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedEightWriter.java new file mode 100644 index 0000000000..c9cc0b72c3 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedEightWriter.java @@ -0,0 +1,108 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class FixedEightWriter implements ValueWriter +{ + private int _written = 9; + private long _value; + + public final int writeToBuffer(ByteBuffer buffer) + { + int remaining = buffer.remaining(); + int written = _written; + switch(written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put(getFormatCode()); + remaining--; + written = 1; + } + else + { + break; + } + case 1: + if(remaining>=8) + { + buffer.putLong(_value); + written = 9; + break; + } + case 2: + case 3: + case 4: + case 5: + if(remaining >= 4) + { + buffer.putInt((int)((_value >> ((5-written)<<3)) & 0xFFFFFFFF )); + remaining-=4; + written+=4; + } + case 6: + case 7: + if(remaining >= 2 && written <= 7) + { + buffer.putShort((short)((_value >> ((7-written)<<3)) & 0xFFFF )); + remaining -= 2; + written += 2; + } + case 8: + if(remaining >=1 && written != 9) + { + buffer.put((byte)((_value >> ((8-written)<<3)) & 0xFF )); + written++; + } + + + } + _written = written; + + return 9; + } + + abstract byte getFormatCode(); + + public final void setValue(T value) + { + _written = 0; + _value = convertValueToLong(value); + } + + abstract long convertValueToLong(T value); + + public boolean isCacheable() + { + return true; + } + + public final boolean isComplete() + { + return _written == 9; + } + + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedFourWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedFourWriter.java new file mode 100644 index 0000000000..164a869299 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedFourWriter.java @@ -0,0 +1,122 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class FixedFourWriter implements ValueWriter +{ + private int _written = 5; + private int _value; + + public final int writeToBuffer(ByteBuffer buffer) + { + int remaining = buffer.remaining(); + int written = _written; + switch(written) + { + case 0: + if(remaining-- != 0) + { + buffer.put(getFormatCode()); + written = 1; + } + else + { + break; + } + case 1: + if(remaining>=4) + { + buffer.putInt(_value); + written = 5; + break; + } + else if(remaining-- != 0) + { + buffer.put((byte)((_value >> 24)&0xFF)); + written = 2; + } + else + { + break; + } + case 2: + if(remaining-- != 0) + { + buffer.put((byte)((_value >> 16)&0xFF)); + written = 3; + } + else + { + break; + } + case 3: + if(remaining-- != 0) + { + buffer.put((byte)((_value >> 8)&0xFF)); + written = 4; + } + else + { + break; + } + case 4: + if(remaining-- != 0) + { + buffer.put((byte)(_value&0xFF)); + written = 5; + } + + } + _written = written; + + return 5; + } + + abstract byte getFormatCode(); + + public final void setValue(T value) + { + if(_written==1) + { + // TODO - remove + System.out.println("Remove"); + } + _written = 0; + _value = convertValueToInt(value); + } + + abstract int convertValueToInt(T value); + + public boolean isCacheable() + { + return true; + } + + public final boolean isComplete() + { + return _written == 5; + } + + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedOneWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedOneWriter.java new file mode 100644 index 0000000000..805b0743a4 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedOneWriter.java @@ -0,0 +1,79 @@ +/* + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + + +public abstract class FixedOneWriter implements ValueWriter +{ + protected int _written = 2; + protected byte _value; + + public int writeToBuffer(ByteBuffer buffer) + { + + switch(_written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put(getFormatCode()); + } + else + { + break; + } + case 1: + if(buffer.hasRemaining()) + { + buffer.put(_value); + _written = 2; + } + else + { + _written = 1; + } + + } + + return 2; + } + + protected abstract byte getFormatCode(); + + public boolean isComplete() + { + return _written == 2; + } + + public boolean isCacheable() + { + return true; + } + + public void setValue(final T value) + { + _written = 0; + _value = convertToByte(value); + } + + protected abstract byte convertToByte(final T value); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedSixteenWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedSixteenWriter.java new file mode 100644 index 0000000000..20334595db --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedSixteenWriter.java @@ -0,0 +1,150 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class FixedSixteenWriter implements ValueWriter +{ + private int _written = 17; + private long _msb; + private long _lsb; + + public final int writeToBuffer(ByteBuffer buffer) + { + int remaining = buffer.remaining(); + int written = _written; + switch(written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put(getFormatCode()); + remaining--; + written = 1; + } + else + { + break; + } + case 1: + if(remaining>=8) + { + buffer.putLong(_msb); + written = 9; + break; + } + case 2: + case 3: + case 4: + case 5: + if(remaining >= 4) + { + buffer.putInt((int)((_msb >> ((5-written)<<3)) & 0xFFFFFFFF )); + remaining-=4; + written+=4; + } + case 6: + case 7: + if(remaining >= 2 && written <= 7) + { + buffer.putShort((short)((_msb >> ((7-written)<<3)) & 0xFFFF )); + remaining -= 2; + written += 2; + } + case 8: + if(remaining >=1 && written != 9) + { + buffer.put((byte)((_msb >> ((8-written)<<3)) & 0xFF )); + written++; + } + + + } + if(remaining != 0) + { + switch(written) + { + case 9: + if(remaining>=8) + { + buffer.putLong(_lsb); + written = 17; + break; + } + case 10: + case 11: + case 12: + case 13: + if(remaining >= 4) + { + buffer.putInt((int)((_lsb >> ((13-written)<<3)) & 0xFFFFFFFF )); + remaining-=4; + written+=4; + } + case 14: + case 15: + if(remaining >= 2 && written <= 15) + { + buffer.putShort((short)((_lsb >> ((15-written)<<3)) & 0xFFFF )); + remaining -= 2; + written += 2; + } + case 16: + if(remaining >=1 && written != 17) + { + buffer.put((byte)((_msb >> ((16-written)<<3)) & 0xFF )); + written++; + } + } + + } + + _written = written; + + return 17; + } + + abstract byte getFormatCode(); + + public final void setValue(T value) + { + _written = 0; + _msb = convertValueToMSB(value); + _lsb = convertValueToLSB(value); + } + + abstract long convertValueToMSB(T value); + abstract long convertValueToLSB(T value); + + public boolean isCacheable() + { + return true; + } + + public final boolean isComplete() + { + return _written == 17; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedTwoWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedTwoWriter.java new file mode 100644 index 0000000000..f6da0490a6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedTwoWriter.java @@ -0,0 +1,96 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class FixedTwoWriter implements ValueWriter +{ + private int _written = 3; + private short _value; + + public int writeToBuffer(ByteBuffer buffer) + { + + switch(_written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put(getFormatCode()); + } + else + { + break; + } + case 1: + + if(buffer.remaining()>1) + { + buffer.putShort(_value); + _written = 3; + } + else if(buffer.hasRemaining()) + { + buffer.put((byte) (0xFF & (_value >> 8))); + _written = 2; + } + else + { + _written = 1; + } + break; + case 2: + if(buffer.hasRemaining()) + { + buffer.put((byte)(0xFF & _value)); + } + + + } + + return 3; + } + + + public final void setValue(T value) + { + _written = 0; + _value = convertValueToShort(value); + } + + abstract short convertValueToShort(T value); + + public boolean isCacheable() + { + return true; + } + + public boolean isComplete() + { + return _written == 3; + } + + abstract byte getFormatCode(); + + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatTypeConstructor.java new file mode 100644 index 0000000000..200fead74e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatTypeConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class FloatTypeConstructor implements TypeConstructor +{ + private static final FloatTypeConstructor INSTANCE = new FloatTypeConstructor(); + + + public static FloatTypeConstructor getInstance() + { + return INSTANCE; + } + + private FloatTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=4) + { + return in.getFloat(); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct float: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatWriter.java new file mode 100644 index 0000000000..823e33c3f8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatWriter.java @@ -0,0 +1,54 @@ +/* + * + * 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.amqp_1_0.codec; + +public class FloatWriter extends FixedFourWriter +{ + private static final byte FORMAT_CODE = (byte)0x72; + + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + @Override + int convertValueToInt(Float value) + { + return Float.floatToIntBits(value.floatValue()); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new FloatWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Float.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java new file mode 100644 index 0000000000..dbf9306366 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java @@ -0,0 +1,245 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.framing.AMQFrame; + +import java.nio.ByteBuffer; + +public class FrameWriter implements ValueWriter +{ + private Registry _registry; + private AMQFrame _frame; + private State _state = State.DONE; + private ValueWriter _typeWriter; + private int _size = -1; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[] {}; + private ByteBuffer _payload; + + enum State + { + SIZE_0, + SIZE_1, + SIZE_2, + SIZE_3, + DOFF, + TYPE, + CHANNEL_0, + CHANNEL_1, + DELEGATE, + PAYLOAD, + DONE + } + + public FrameWriter(final Registry registry) + { + _registry = registry; + } + + public boolean isComplete() + { + return _state == State.DONE; + } + + public boolean isCacheable() + { + return false; + } + + public int writeToBuffer(ByteBuffer buffer) + { + int remaining; + + + + while((remaining = buffer.remaining()) != 0 && _state != State.DONE) + { + switch(_state) + { + case SIZE_0: + + _typeWriter.setValue(_frame.getFrameBody()); + + int payloadLength = _payload == null ? 0 : _payload.remaining(); + + _size = _typeWriter.writeToBuffer(remaining > 8 + ? (ByteBuffer)buffer.duplicate().position(buffer.position()+8) + : ByteBuffer.wrap(EMPTY_BYTE_ARRAY)) + 8 + payloadLength; + if(remaining >= 4) + { + buffer.putInt(_size); + + if(remaining >= 8) + { + buffer.put((byte)2); // DOFF + buffer.put(_frame.getFrameType()); // AMQP Frame Type + buffer.putShort(_frame.getChannel()); + + if(_size - payloadLength > remaining) + { + buffer.position(buffer.limit()); + _state = State.DELEGATE; + } + else if(_size > remaining ) + { + buffer.position(buffer.position()+_size-8-payloadLength); + if(payloadLength > 0) + { + + ByteBuffer dup = _payload.slice(); + int payloadUsed = buffer.remaining(); + dup.limit(payloadUsed); + buffer.put(dup); + _payload.position(_payload.position()+payloadUsed); + } + _state = State.PAYLOAD; + } + else + { + + buffer.position(buffer.position()+_size-8-payloadLength); + if(payloadLength > 0) + { + buffer.put(_payload); + } + _state = State.DONE; + } + + } + else + { + _state = State.DOFF; + } + break; + } + else + { + buffer.put((byte)((_size >> 24) & 0xFF)); + if(!buffer.hasRemaining()) + { + _state = State.SIZE_1; + break; + } + } + + case SIZE_1: + buffer.put((byte)((_size >> 16) & 0xFF)); + if(!buffer.hasRemaining()) + { + _state = State.SIZE_2; + break; + } + case SIZE_2: + buffer.put((byte)((_size >> 8) & 0xFF)); + if(!buffer.hasRemaining()) + { + _state = State.SIZE_3; + break; + } + case SIZE_3: + buffer.put((byte)(_size & 0xFF)); + if(!buffer.hasRemaining()) + { + _state = State.DOFF; + break; + } + case DOFF: + buffer.put((byte)2); // Always 2 (8 bytes) + if(!buffer.hasRemaining()) + { + _state = State.TYPE; + break; + } + case TYPE: + buffer.put((byte)0); + if(!buffer.hasRemaining()) + { + _state = State.CHANNEL_0; + break; + } + case CHANNEL_0: + buffer.put((byte)((_frame.getChannel() >> 8) & 0xFF)); + if(!buffer.hasRemaining()) + { + _state = State.CHANNEL_1; + break; + } + case CHANNEL_1: + buffer.put((byte)(_frame.getChannel() & 0xFF)); + if(!buffer.hasRemaining()) + { + _state = State.DELEGATE; + break; + } + case DELEGATE: + _typeWriter.writeToBuffer(buffer); + if(_typeWriter.isComplete()) + { + _state = State.PAYLOAD; + _frame = null; + _typeWriter = null; + } + else + { + break; + } + case PAYLOAD: + if(_payload == null || _payload.remaining() == 0) + { + _state = State.DONE; + _frame = null; + _typeWriter = null; + _payload = null; + + } + else if(buffer.hasRemaining()) + { + buffer.put(_payload); + if(_payload.remaining() == 0) + { + _state = State.DONE; + _frame = null; + _typeWriter = null; + _payload = null; + } + } + + } + } + if(_size == -1) + { + _size = _typeWriter.writeToBuffer(ByteBuffer.wrap(EMPTY_BYTE_ARRAY)) + 8 + (_payload == null ? 0 : _payload.remaining()); + } + return _size; + } + + public void setValue(AMQFrame frame) + { + _frame = frame; + _state = State.SIZE_0; + _size = -1; + _payload = null; + final Object frameBody = frame.getFrameBody(); + _typeWriter = _registry.getValueWriter(frameBody); + _payload = frame.getPayload() == null ? null : frame.getPayload().duplicate(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntTypeConstructor.java new file mode 100644 index 0000000000..b3e774de5c --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntTypeConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class IntTypeConstructor implements TypeConstructor +{ + private static final IntTypeConstructor INSTANCE = new IntTypeConstructor(); + + + public static IntTypeConstructor getInstance() + { + return INSTANCE; + } + + private IntTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=4) + { + return in.getInt(); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct int: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntegerWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntegerWriter.java new file mode 100644 index 0000000000..91c3151494 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntegerWriter.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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class IntegerWriter implements ValueWriter +{ + private static final byte EIGHT_BYTE_FORMAT_CODE = (byte)0x71; + private static final byte ONE_BYTE_FORMAT_CODE = (byte) 0x54; + + private ValueWriter _delegate; + + private final FixedFourWriter _eightByteWriter = new FixedFourWriter() + { + + @Override + byte getFormatCode() + { + return EIGHT_BYTE_FORMAT_CODE; + } + + @Override + int convertValueToInt(Integer value) + { + return value.intValue(); + } + }; + + private final ValueWriter _oneByteWriter = new FixedOneWriter() + { + + @Override protected byte getFormatCode() + { + return ONE_BYTE_FORMAT_CODE; + } + + @Override protected byte convertToByte(final Integer value) + { + return value.byteValue(); + } + }; + + + public int writeToBuffer(final ByteBuffer buffer) + { + return _delegate.writeToBuffer(buffer); + } + + public void setValue(final Integer i) + { + if(i >= -128 && i <= 127) + { + _delegate = _oneByteWriter; + } + else + { + _delegate = _eightByteWriter; + } + _delegate.setValue(i); + } + + public boolean isComplete() + { + return _delegate.isComplete(); + } + + public boolean isCacheable() + { + return false; + } + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new IntegerWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Integer.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ListWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ListWriter.java new file mode 100644 index 0000000000..3e0164705f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ListWriter.java @@ -0,0 +1,172 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; +import java.util.List; + +public class ListWriter implements ValueWriter +{ + private static class NonEmptyListWriter extends AbstractListWriter + { + private List _list; + private int _position = 0; + + public NonEmptyListWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final List value) + { + _list = value; + _position = 0; + + } + + @Override + protected int getCount() + { + return _list.size(); + } + + @Override + protected boolean hasNext() + { + return _position < getCount(); + } + + @Override + protected Object next() + { + return _list.get(_position++); + } + + @Override + protected void clear() + { + _list = null; + _position = 0; + } + + @Override + protected void reset() + { + _position = 0; + } + + } + + private final NonEmptyListWriter _nonEmptyListWriter; + private static final byte ZERO_BYTE_FORMAT_CODE = (byte) 0x45; + + private final ValueWriter _emptyListWriter = new EmptyListValueWriter(); + + + private ValueWriter _delegate; + + public ListWriter(final Registry registry) + { + _nonEmptyListWriter = new NonEmptyListWriter(registry); + + } + + + public int writeToBuffer(ByteBuffer buffer) + { + return _delegate.writeToBuffer(buffer); + } + + public void setValue(List frameBody) + { + if(frameBody.isEmpty()) + { + _delegate = _emptyListWriter; + } + else + { + _delegate = _nonEmptyListWriter; + } + _delegate.setValue(frameBody); + } + + public boolean isComplete() + { + return _delegate.isComplete(); + } + + public boolean isCacheable() + { + return false; + } + + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ListWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(List.class, FACTORY); + } + + public static class EmptyListValueWriter implements ValueWriter + { + private boolean _complete; + + + public int writeToBuffer(ByteBuffer buffer) + { + + if(!_complete && buffer.hasRemaining()) + { + buffer.put(ZERO_BYTE_FORMAT_CODE); + _complete = true; + } + + return 1; + } + + public void setValue(List list) + { + _complete = false; + } + + public boolean isCacheable() + { + return true; + } + + public boolean isComplete() + { + return _complete; + } + + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongTypeConstructor.java new file mode 100644 index 0000000000..b9a4509a04 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongTypeConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class LongTypeConstructor implements TypeConstructor +{ + private static final LongTypeConstructor INSTANCE = new LongTypeConstructor(); + + + public static LongTypeConstructor getInstance() + { + return INSTANCE; + } + + private LongTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=8) + { + return in.getLong(); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct long: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongWriter.java new file mode 100644 index 0000000000..984775cc74 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongWriter.java @@ -0,0 +1,111 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class LongWriter implements ValueWriter +{ + private static final byte EIGHT_BYTE_FORMAT_CODE = (byte) 0x81; + + + private static final byte ONE_BYTE_FORMAT_CODE = (byte) 0x55; + + private ValueWriter _delegate; + + private final FixedEightWriter _eightByteWriter = new FixedEightWriter() + { + + @Override + byte getFormatCode() + { + return EIGHT_BYTE_FORMAT_CODE; + } + + @Override + long convertValueToLong(Long value) + { + return value; + } + + }; + + private final ValueWriter _oneByteWriter = new FixedOneWriter() + { + + @Override protected byte getFormatCode() + { + return ONE_BYTE_FORMAT_CODE; + } + + @Override protected byte convertToByte(final Long value) + { + return value.byteValue(); + } + }; + + public int writeToBuffer(final ByteBuffer buffer) + { + return _delegate.writeToBuffer(buffer); + } + + public void setValue(final Long l) + { + if(l >= -128 && l <= 127) + { + _delegate = _oneByteWriter; + } + else + { + _delegate = _eightByteWriter; + } + _delegate.setValue(l); + } + + public boolean isComplete() + { + return _delegate.isComplete(); + } + + public boolean isCacheable() + { + return false; + } + + + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new LongWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Long.class, FACTORY); + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/MapWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/MapWriter.java new file mode 100644 index 0000000000..b239d4a397 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/MapWriter.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.amqp_1_0.codec; + +import java.util.Iterator; +import java.util.Map; + +public class MapWriter extends AbstractMapWriter +{ + private Map _map; + private Object _value; + private Iterator _iterator; + + public MapWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Map value) + { + _map = value; + _iterator = value.entrySet().iterator(); + } + + @Override + protected int getMapCount() + { + return _map.size(); + } + + @Override + protected boolean hasMapNext() + { + return _iterator.hasNext(); + } + + @Override + protected Object nextKey() + { + Map.Entry entry = _iterator.next(); + _value = entry.getValue(); + return entry.getKey(); + } + @Override + protected Object nextValue() + { + Object value = _value; + _value = null; + return value; + } + + + @Override + protected void onClear() + { + _map = null; + _iterator = null; + _value = null; + } + + @Override + protected void onReset() + { + _iterator = _map.entrySet().iterator(); + _value = null; + } + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new MapWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Map.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullTypeConstructor.java new file mode 100644 index 0000000000..6b46895708 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullTypeConstructor.java @@ -0,0 +1,44 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +import java.nio.ByteBuffer; + +class NullTypeConstructor implements TypeConstructor +{ + private static final NullTypeConstructor INSTANCE = new NullTypeConstructor(); + + NullTypeConstructor() + { + } + + public Void construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return null; + } + + public static NullTypeConstructor getInstance() + { + return INSTANCE; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullWriter.java new file mode 100644 index 0000000000..690a2222ab --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullWriter.java @@ -0,0 +1,70 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public class NullWriter implements ValueWriter +{ + private boolean _complete = true; + + public int writeToBuffer(ByteBuffer buffer) + { + + if(!_complete && buffer.hasRemaining()) + { + buffer.put((byte)0x40); + _complete = true; + } + + return 1; + } + + public void setValue(Void frameBody) + { + _complete = false; + } + + public boolean isCacheable() + { + return true; + } + + public boolean isComplete() + { + return _complete; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new NullWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Void.TYPE, FACTORY); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHandler.java new file mode 100644 index 0000000000..a954c6db50 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHandler.java @@ -0,0 +1,30 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public interface ProtocolHandler +{ + ProtocolHandler parse(ByteBuffer in); + + boolean isDone(); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHeaderHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHeaderHandler.java new file mode 100644 index 0000000000..f72fea56b2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHeaderHandler.java @@ -0,0 +1,146 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.framing.AMQPProtocolHeaderHandler; +import org.apache.qpid.amqp_1_0.framing.SASLProtocolHeaderHandler; + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + +import java.nio.ByteBuffer; + +public class ProtocolHeaderHandler implements ProtocolHandler +{ + private final ConnectionEndpoint _connection; + private ProtocolHandler[] _protocolHandlers = new ProtocolHandler[4]; + private boolean _done; + + enum State { + AWAITING_A, + AWAITING_M, + AWAITING_Q, + AWAITING_P, + AWAITING_PROTOCOL_ID, + ERROR + } + + private State _state = State.AWAITING_A; + + public ProtocolHeaderHandler(final ConnectionEndpoint connection) + { + _connection = connection; + _protocolHandlers[0] = new AMQPProtocolHeaderHandler(connection); + _protocolHandlers[1] = null ; // historic apache.qpid.amqp_1_0 + _protocolHandlers[2] = null ; // TLS + _protocolHandlers[3] = new SASLProtocolHeaderHandler(connection); // SASL + + + } + + public ProtocolHandler parse(final ByteBuffer in) + { + if(!in.hasRemaining()) + { + return this; + } + + switch(_state) + { + case AWAITING_A: + if(transition(in, (byte)'A', State.AWAITING_M)) + { + break; + } + case AWAITING_M: + if(transition(in, (byte)'M', State.AWAITING_Q)) + { + break; + } + case AWAITING_Q: + if(transition(in, (byte)'Q', State.AWAITING_P)) + { + break; + } + + case AWAITING_P: + if(transition(in, (byte)'P', State.AWAITING_PROTOCOL_ID)) + { + break; + } + case AWAITING_PROTOCOL_ID: + int protocolId = ((int) in.get()) & 0xff; + ProtocolHandler delegate; + + try + { + delegate = _protocolHandlers[protocolId]; + } + catch(IndexOutOfBoundsException e) + { + delegate = null; + } + + if(delegate == null) + { + _state = State.ERROR; + } + else + { + return delegate.parse(in); + } + } + if(_state == State.ERROR) + { + _connection.invalidHeaderReceived(); + _done = true; + } + return this; + + } + + boolean transition(ByteBuffer in, byte expected, State next) + { + byte b = in.get(); + if(b == expected) + { + if(!in.hasRemaining()) + { + _state = next; + return true; + } + else + { + return false; + } + } + else + { + _state = State.ERROR; + return true; + } + } + + + public boolean isDone() + { + return _done; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/RestrictedTypeValueWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/RestrictedTypeValueWriter.java new file mode 100644 index 0000000000..cbc8277dc8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/RestrictedTypeValueWriter.java @@ -0,0 +1,55 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.RestrictedType; + +public class RestrictedTypeValueWriter extends DelegatingValueWriter> +{ + public RestrictedTypeValueWriter(final Registry registry) + { + super(registry); + } + + @Override + protected Object getUnderlyingValue(final RestrictedType restrictedType) + { + return restrictedType.getValue(); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new RestrictedTypeValueWriter(registry); + } + }; + + public boolean isCacheable() + { + return true; + } + + public static void register(ValueWriter.Registry registry, Class clazz) + { + registry.register(clazz, FACTORY); + }} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortTypeConstructor.java new file mode 100644 index 0000000000..648ed36c69 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortTypeConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class ShortTypeConstructor implements TypeConstructor +{ + private static final ShortTypeConstructor INSTANCE = new ShortTypeConstructor(); + + + public static ShortTypeConstructor getInstance() + { + return INSTANCE; + } + + private ShortTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=2) + { + return in.getShort(); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct short: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortWriter.java new file mode 100644 index 0000000000..52ec577c3e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortWriter.java @@ -0,0 +1,55 @@ +/* + * + * 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.amqp_1_0.codec; + +public class ShortWriter extends FixedTwoWriter +{ + + private static final byte FORMAT_CODE = (byte)0x61; + + + @Override + short convertValueToShort(Short value) + { + return value.shortValue(); + } + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ShortWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Short.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SimpleVariableWidthWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SimpleVariableWidthWriter.java new file mode 100644 index 0000000000..bd14483361 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SimpleVariableWidthWriter.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class SimpleVariableWidthWriter extends VariableWidthWriter +{ + private byte[] _buf; + + + public void setValue(V value) + { + _buf = getByteArray(value); + super.setValue(value); + } + + protected int getLength() + { + return _buf.length; + } + + protected void writeBytes(ByteBuffer buf, int offset, int length) + { + buf.put(_buf, getOffset()+offset, length); + } + + @Override + protected void clearValue() + { + _buf = null; + } + + @Override + protected boolean hasValue() + { + return _buf != null; + } + + public boolean isCacheable() + { + return true; + } + + protected abstract byte[] getByteArray(V value); + + protected abstract int getOffset(); + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallIntConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallIntConstructor.java new file mode 100644 index 0000000000..07fa853dce --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallIntConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class SmallIntConstructor implements TypeConstructor +{ + private static final SmallIntConstructor INSTANCE = new SmallIntConstructor(); + + + public static SmallIntConstructor getInstance() + { + return INSTANCE; + } + + private SmallIntConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + byte b = in.get(); + return (int) b; + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct int: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallLongConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallLongConstructor.java new file mode 100644 index 0000000000..013b9bef64 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallLongConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class SmallLongConstructor implements TypeConstructor +{ + private static final SmallLongConstructor INSTANCE = new SmallLongConstructor(); + + + public static SmallLongConstructor getInstance() + { + return INSTANCE; + } + + private SmallLongConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + byte b = in.get(); + return (long) b; + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct long: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallUIntConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallUIntConstructor.java new file mode 100644 index 0000000000..b3a9e3ef19 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallUIntConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class SmallUIntConstructor implements TypeConstructor +{ + private static final SmallUIntConstructor INSTANCE = new SmallUIntConstructor(); + + + public static SmallUIntConstructor getInstance() + { + return INSTANCE; + } + + private SmallUIntConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + byte b = in.get(); + return UnsignedInteger.valueOf(((int) b) & 0xff); + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct uint: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallULongConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallULongConstructor.java new file mode 100644 index 0000000000..38cd0b65ac --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallULongConstructor.java @@ -0,0 +1,59 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; + +public class SmallULongConstructor implements TypeConstructor +{ + private static final SmallULongConstructor INSTANCE = new SmallULongConstructor(); + + + public static SmallULongConstructor getInstance() + { + return INSTANCE; + } + + private SmallULongConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + byte b = in.get(); + return UnsignedLong.valueOf(((long) b) & 0xffL); + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct ulong: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringTypeConstructor.java new file mode 100644 index 0000000000..73b85d4163 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringTypeConstructor.java @@ -0,0 +1,132 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.LinkedHashMap; +import java.util.Map; + +public class StringTypeConstructor extends VariableWidthTypeConstructor +{ + private Charset _charSet; + + private BinaryString _defaultBinaryString = new BinaryString(); + private ValueCache _cachedValues = new ValueCache(10); + + private static final class ValueCache extends LinkedHashMap + { + private final int _cacheSize; + + public ValueCache(int cacheSize) + { + _cacheSize = cacheSize; + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) + { + return size() > _cacheSize; + } + + public boolean isFull() + { + return size() == _cacheSize; + } + } + + + public static StringTypeConstructor getInstance(int i, Charset c) + { + return new StringTypeConstructor(i, c); + } + + + private StringTypeConstructor(int size, Charset c) + { + super(size); + _charSet = c; + } + + @Override + public Object construct(final ByteBuffer in, boolean isCopy, ValueHandler handler) throws AmqpErrorException + { + int size; + + if(getSize() == 1) + { + size = in.get() & 0xFF; + } + else + { + size = in.getInt(); + } + + int origPosition = in.position(); + _defaultBinaryString.setData(in.array(), in.arrayOffset()+ origPosition, size); + + BinaryString binaryStr = _defaultBinaryString; + + boolean isFull = _cachedValues.isFull(); + + String str = isFull ? _cachedValues.remove(binaryStr) : _cachedValues.get(binaryStr); + + if(str == null) + { + + ByteBuffer dup = in.duplicate(); + try + { + dup.limit(dup.position()+size); + } + catch(IllegalArgumentException e) + { + throw new IllegalArgumentException("position: " + dup.position() + "size: " + size + " capacity: " + dup.capacity()); + } + CharBuffer charBuf = _charSet.decode(dup); + + str = charBuf.toString(); + + byte[] data = new byte[size]; + in.get(data); + binaryStr = new BinaryString(data, 0, size); + + _cachedValues.put(binaryStr, str); + } + else if(isFull) + { + byte[] data = new byte[size]; + in.get(data); + binaryStr = new BinaryString(data, 0, size); + + _cachedValues.put(binaryStr, str); + } + + in.position(origPosition+size); + + return str; + + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringWriter.java new file mode 100644 index 0000000000..39f759e54d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringWriter.java @@ -0,0 +1,146 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.util.LinkedHashMap; +import java.util.Map; + +public class StringWriter extends SimpleVariableWidthWriter +{ + private static final Charset ENCODING_CHARSET; + private static final byte ONE_BYTE_CODE; + private static final byte FOUR_BYTE_CODE; + static + { + Charset defaultCharset = Charset.defaultCharset(); + if(defaultCharset.name().equals("UTF-16") || defaultCharset.name().equals("UTF-16BE")) + { + ENCODING_CHARSET = defaultCharset; + ONE_BYTE_CODE = (byte) 0xa2; + FOUR_BYTE_CODE = (byte) 0xb2; + } + else + { + ENCODING_CHARSET = Charset.forName("UTF-8"); + ONE_BYTE_CODE = (byte) 0xa1; + FOUR_BYTE_CODE = (byte) 0xb1; + } + } + + private static final class ValueCache extends LinkedHashMap + { + private final int _cacheSize; + + public ValueCache(int cacheSize) + { + _cacheSize = cacheSize; + } + + @Override + protected boolean removeEldestEntry(Map.Entry eldest) + { + return size() > _cacheSize; + } + + public boolean isFull() + { + return size() == _cacheSize; + } + } + + private final ValueCache _cachedEncodings = new ValueCache(10); + + + @Override + protected byte getFourOctetEncodingCode() + { + return FOUR_BYTE_CODE; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return ONE_BYTE_CODE; + } + + @Override + protected byte[] getByteArray(String value) + { + + byte[] encoding; + boolean isFull = _cachedEncodings.isFull(); + if(isFull) + { + encoding = _cachedEncodings.remove(value); + } + else + { + encoding = _cachedEncodings.get(value); + } + + + if(encoding == null) + { + ByteBuffer buf = ENCODING_CHARSET.encode(value); + if(buf.hasArray() && buf.arrayOffset() == 0 && buf.limit()==buf.capacity()) + { + encoding = buf.array(); + } + else + { + byte[] bufArray = new byte[buf.limit()-buf.position()]; + buf.get(bufArray); + encoding = bufArray; + } + _cachedEncodings.put(value,encoding); + + } + else if(isFull) + { + _cachedEncodings.put(value,encoding); + } + + return encoding; + } + + @Override + protected int getOffset() + { + return 0; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new StringWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(String.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolArrayWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolArrayWriter.java new file mode 100644 index 0000000000..234a6afe24 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolArrayWriter.java @@ -0,0 +1,170 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.Symbol; + +import java.nio.ByteBuffer; + +public class SymbolArrayWriter extends VariableWidthWriter +{ + + private int _length; + private byte[] _encodedVal; + + @Override protected void clearValue() + { + _encodedVal = null; + } + + @Override protected boolean hasValue() + { + return _encodedVal != null; + } + + @Override protected byte getFourOctetEncodingCode() + { + return (byte) 0xf0; + } + + @Override protected byte getSingleOctetEncodingCode() + { + return (byte) 0xe0; + } + + @Override protected int getLength() + { + return _length; + } + + @Override protected void writeBytes(final ByteBuffer buf, final int offset, final int length) + { + buf.put(_encodedVal,offset,length); + } + + public boolean isCacheable() + { + return false; + } + + public void setValue(final Symbol[] value) + { + + boolean useSmallConstructor = useSmallConstructor(value); + boolean isSmall = useSmallConstructor && canFitInSmall(value); + if(isSmall) + { + _length = 2; + } + else + { + _length = 5; + } + for(Symbol symbol : value) + { + _length += symbol.length() ; + } + _length += value.length * (useSmallConstructor ? 1 : 4); + + + _encodedVal = new byte[_length]; + + ByteBuffer buf = ByteBuffer.wrap(_encodedVal); + if(isSmall) + { + buf.put((byte)value.length); + buf.put(SymbolWriter.SMALL_ENCODING_CODE); + } + else + { + buf.putInt(value.length); + buf.put(SymbolWriter.LARGE_ENCODING_CODE); + } + + for(Symbol symbol : value) + { + if(isSmall) + { + buf.put((byte)symbol.length()); + } + else + { + buf.putInt(symbol.length()); + } + + + for(int i = 0; i < symbol.length(); i++) + { + buf.put((byte)symbol.charAt(i)); + } + } + + + + super.setValue(value); + } + + private boolean useSmallConstructor(final Symbol[] value) + { + for(Symbol sym : value) + { + if(sym.length()>255) + { + return false; + } + } + return true; + } + + private boolean canFitInSmall(final Symbol[] value) + { + if(value.length>=127) + { + return false; + } + + int remaining = 253 - value.length; + for(Symbol symbol : value) + { + + if((remaining -= symbol.length()) < 0) + { + return false; + } + } + + return true; + } + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new SymbolArrayWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Symbol[].class, FACTORY); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java new file mode 100644 index 0000000000..ce0f5cb26b --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java @@ -0,0 +1,109 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Symbol; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.concurrent.ConcurrentHashMap; + +public class SymbolTypeConstructor extends VariableWidthTypeConstructor +{ + private static final Charset ASCII = Charset.forName("US-ASCII"); + + private BinaryString _defaultBinaryString = new BinaryString(); + + private static final ConcurrentHashMap SYMBOL_MAP = + new ConcurrentHashMap(2048); + + public static SymbolTypeConstructor getInstance(int i) + { + return new SymbolTypeConstructor(i); + } + + + private SymbolTypeConstructor(int size) + { + super(size); + } + + @Override + public Object construct(final ByteBuffer in, boolean isCopy, ValueHandler handler) throws AmqpErrorException + { + int size; + + if(getSize() == 1) + { + size = in.get() & 0xFF; + } + else + { + size = in.getInt(); + } + + _defaultBinaryString.setData(in.array(), in.arrayOffset()+in.position(), size); + + BinaryString binaryStr = _defaultBinaryString; + + Symbol symbolVal = SYMBOL_MAP.get(binaryStr); + if(symbolVal == null) + { + ByteBuffer dup = in.duplicate(); + try + { + dup.limit(in.position()+size); + } + catch (IllegalArgumentException e) + { + System.err.println("in.position(): " + in.position()); + System.err.println("size: " + size); + System.err.println("dup.position(): " + dup.position()); + System.err.println("dup.capacity(): " + dup.capacity()); + System.err.println("dup.limit(): " + dup.limit()); + throw e; + + } + CharBuffer charBuf = ASCII.decode(dup); + + + symbolVal = Symbol.getSymbol(charBuf.toString()); + + + + + byte[] data = new byte[size]; + in.get(data); + binaryStr = new BinaryString(data, 0, size); + SYMBOL_MAP.putIfAbsent(binaryStr, symbolVal); + } + else + { + in.position(in.position()+size); + } + + return symbolVal; + + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolWriter.java new file mode 100644 index 0000000000..ae43c7ebd2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolWriter.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.Symbol; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +public class SymbolWriter extends VariableWidthWriter +{ + private static final Charset ENCODING_CHARSET = Charset.forName("US-ASCII"); + public static final byte LARGE_ENCODING_CODE = (byte) 0xb3; + public static final byte SMALL_ENCODING_CODE = (byte) 0xa3; + private Symbol _value; + + + @Override + protected byte getFourOctetEncodingCode() + { + return LARGE_ENCODING_CODE; + } + + @Override + protected byte getSingleOctetEncodingCode() + { + return SMALL_ENCODING_CODE; + } + + @Override + public void setValue(Symbol value) + { + _value = value; + super.setValue(value); + } + + public boolean isCacheable() + { + return true; + } + + @Override + protected void clearValue() + { + _value = null; + } + + @Override + protected boolean hasValue() + { + return _value != null; + } + + @Override + protected int getLength() + { + return _value.length(); + } + + @Override + protected void writeBytes(ByteBuffer buf, int offset, int length) + { + int end = offset + length; + for(int i = offset; i < end; i++) + { + buf.put((byte)_value.charAt(i)); + } + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new SymbolWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Symbol.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampTypeConstructor.java new file mode 100644 index 0000000000..d826e0ee56 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampTypeConstructor.java @@ -0,0 +1,60 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; +import java.util.Date; + +public class TimestampTypeConstructor implements TypeConstructor +{ + private static final TimestampTypeConstructor INSTANCE = new TimestampTypeConstructor(); + + + public static TimestampTypeConstructor getInstance() + { + return INSTANCE; + } + + private TimestampTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=8) + { + long l = in.getLong(); + return new Date(l); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct timestamp: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampWriter.java new file mode 100644 index 0000000000..153c51b7c7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampWriter.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. + * + */ + +package org.apache.qpid.amqp_1_0.codec; + +import java.util.Date; + +public class TimestampWriter extends FixedEightWriter +{ + private static final byte FORMAT_CODE = (byte) 0x83; + + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + @Override + long convertValueToLong(Date value) + { + return value.getTime(); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new TimestampWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Date.class, FACTORY); + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TypeConstructor.java new file mode 100644 index 0000000000..8b433e4b20 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TypeConstructor.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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +public interface TypeConstructor +{ + + public T construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException; + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UByteTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UByteTypeConstructor.java new file mode 100644 index 0000000000..7ff5abc558 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UByteTypeConstructor.java @@ -0,0 +1,59 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class UByteTypeConstructor implements TypeConstructor +{ + private static final UByteTypeConstructor INSTANCE = new UByteTypeConstructor(); + + + public static UByteTypeConstructor getInstance() + { + return INSTANCE; + } + + private UByteTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.hasRemaining()) + { + byte b = in.get(); + return UnsignedByte.valueOf(b); + } + else + { + Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct ubyte: insufficient input data"); + throw new AmqpErrorException(error); + } + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UIntTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UIntTypeConstructor.java new file mode 100644 index 0000000000..fc0c433d7c --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UIntTypeConstructor.java @@ -0,0 +1,59 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class UIntTypeConstructor implements TypeConstructor +{ + private static final UIntTypeConstructor INSTANCE = new UIntTypeConstructor(); + + + public static UIntTypeConstructor getInstance() + { + return INSTANCE; + } + + private UIntTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=4) + { + final int i = in.getInt(); + return UnsignedInteger.valueOf(i); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct uint: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ULongTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ULongTypeConstructor.java new file mode 100644 index 0000000000..550a61b4fa --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ULongTypeConstructor.java @@ -0,0 +1,61 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class ULongTypeConstructor implements TypeConstructor +{ + private static final ULongTypeConstructor INSTANCE = new ULongTypeConstructor(); + + + public static ULongTypeConstructor getInstance() + { + return INSTANCE; + } + + private ULongTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=8) + { + long l = in.getLong(); + + return UnsignedLong.valueOf(l); + + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new org.apache.qpid.amqp_1_0.type.transport.Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct ulong: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UShortTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UShortTypeConstructor.java new file mode 100644 index 0000000000..6cf7cb5dca --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UShortTypeConstructor.java @@ -0,0 +1,60 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; + +public class UShortTypeConstructor implements TypeConstructor +{ + private static final UShortTypeConstructor INSTANCE = new UShortTypeConstructor(); + + + public static UShortTypeConstructor getInstance() + { + return INSTANCE; + } + + private UShortTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=2) + { + short s = in.getShort(); + return UnsignedShort.valueOf(s); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct ushort: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDTypeConstructor.java new file mode 100644 index 0000000000..c34a8fca65 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDTypeConstructor.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. + * + */ +package org.apache.qpid.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; +import java.util.UUID; + +public class UUIDTypeConstructor implements TypeConstructor +{ + private static final UUIDTypeConstructor INSTANCE = new UUIDTypeConstructor(); + + + public static UUIDTypeConstructor getInstance() + { + return INSTANCE; + } + + private UUIDTypeConstructor() + { + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + if(in.remaining()>=16) + { + long msb = in.getLong(); + long lsb = in.getLong(); + return new UUID(msb, lsb); + } + else + { + org.apache.qpid.amqp_1_0.type.transport.Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("Cannot construct UUID: insufficient input data"); + throw new AmqpErrorException(error); + + } + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDWriter.java new file mode 100644 index 0000000000..b900fd63ce --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDWriter.java @@ -0,0 +1,63 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.util.UUID; + +public class UUIDWriter extends FixedSixteenWriter +{ + private static final byte FORMAT_CODE = (byte) 0x98; + + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + @Override + long convertValueToMSB(UUID value) + { + return value.getMostSignificantBits(); + } + + @Override + long convertValueToLSB(UUID value) + { + return value.getLeastSignificantBits(); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new UUIDWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(UUID.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedByteWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedByteWriter.java new file mode 100644 index 0000000000..aedf3811d9 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedByteWriter.java @@ -0,0 +1,92 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.UnsignedByte; + +import java.nio.ByteBuffer; + +public class UnsignedByteWriter implements ValueWriter +{ + private int _written; + private byte _value; + + public int writeToBuffer(ByteBuffer buffer) + { + + switch(_written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put((byte)0x50); + } + else + { + break; + } + case 1: + if(buffer.hasRemaining()) + { + buffer.put(_value); + _written = 2; + } + else + { + _written = 1; + } + + } + + return 2; + } + + public void setValue(UnsignedByte value) + { + _written = 0; + _value = value.byteValue(); + } + + public boolean isComplete() + { + return _written == 2; + } + + public boolean isCacheable() + { + return true; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new UnsignedByteWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(UnsignedByte.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedIntegerWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedIntegerWriter.java new file mode 100644 index 0000000000..9517bd9c6e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedIntegerWriter.java @@ -0,0 +1,148 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; + +import java.nio.ByteBuffer; + +public class UnsignedIntegerWriter implements ValueWriter +{ + private static final byte EIGHT_BYTE_FORMAT_CODE = (byte)0x70; + private static final byte ONE_BYTE_FORMAT_CODE = (byte) 0x52; + private static final byte ZERO_BYTE_FORMAT_CODE = (byte) 0x43; + + private ValueWriter _delegate; + + private final FixedFourWriter _eightByteWriter = new FixedFourWriter() + { + + @Override + byte getFormatCode() + { + return EIGHT_BYTE_FORMAT_CODE; + } + + @Override + int convertValueToInt(UnsignedInteger value) + { + return value.intValue(); + } + }; + + private final ValueWriter _oneByteWriter = new FixedOneWriter() + { + + @Override protected byte getFormatCode() + { + return ONE_BYTE_FORMAT_CODE; + } + + @Override protected byte convertToByte(final UnsignedInteger value) + { + return value.byteValue(); + } + }; + + private final ValueWriter _zeroByteWriter = new ValueWriter() + { + private boolean _complete; + + + public int writeToBuffer(ByteBuffer buffer) + { + + if(!_complete && buffer.hasRemaining()) + { + buffer.put(ZERO_BYTE_FORMAT_CODE); + _complete = true; + } + + return 1; + } + + public void setValue(UnsignedInteger uint) + { + _complete = false; + } + + public boolean isCacheable() + { + return true; + } + + public boolean isComplete() + { + return _complete; + } + + }; + + + + public int writeToBuffer(final ByteBuffer buffer) + { + return _delegate.writeToBuffer(buffer); + } + + public void setValue(final UnsignedInteger uint) + { + if(uint.equals(UnsignedInteger.ZERO)) + { + _delegate = _zeroByteWriter; + } + else if(uint.compareTo(UnsignedInteger.valueOf(256))<0) + { + _delegate = _oneByteWriter; + } + else + { + _delegate = _eightByteWriter; + } + _delegate.setValue(uint); + } + + public boolean isComplete() + { + return _delegate.isComplete(); + } + + public boolean isCacheable() + { + return false; + } + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new UnsignedIntegerWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(UnsignedInteger.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedLongWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedLongWriter.java new file mode 100644 index 0000000000..4345187d61 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedLongWriter.java @@ -0,0 +1,152 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; + +import java.nio.ByteBuffer; + +public class UnsignedLongWriter implements ValueWriter +{ + + + private static final byte EIGHT_BYTE_FORMAT_CODE = (byte) 0x80; + private static final byte ONE_BYTE_FORMAT_CODE = (byte) 0x53; + private static final byte ZERO_BYTE_FORMAT_CODE = (byte) 0x44; + + private ValueWriter _delegate; + + private final FixedEightWriter _eightByteWriter = new FixedEightWriter() + { + + @Override + byte getFormatCode() + { + return EIGHT_BYTE_FORMAT_CODE; + } + + @Override + long convertValueToLong(UnsignedLong value) + { + return value.longValue(); + } + + }; + + private final ValueWriter _oneByteWriter = new FixedOneWriter() + { + + @Override protected byte getFormatCode() + { + return ONE_BYTE_FORMAT_CODE; + } + + @Override protected byte convertToByte(final UnsignedLong value) + { + return value.byteValue(); + } + }; + + private final ValueWriter _zeroByteWriter = new ValueWriter() + { + private boolean _complete; + + + public int writeToBuffer(ByteBuffer buffer) + { + + if(!_complete && buffer.hasRemaining()) + { + buffer.put(ZERO_BYTE_FORMAT_CODE); + _complete = true; + } + + return 1; + } + + public void setValue(UnsignedLong ulong) + { + _complete = false; + } + + public boolean isCacheable() + { + return true; + } + + public boolean isComplete() + { + return _complete; + } + + }; + + + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new UnsignedLongWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(UnsignedLong.class, FACTORY); + } + + public int writeToBuffer(final ByteBuffer buffer) + { + return _delegate.writeToBuffer(buffer); + } + + public void setValue(final UnsignedLong ulong) + { + if(ulong.equals(UnsignedLong.ZERO)) + { + _delegate = _zeroByteWriter; + } + else if(ulong.compareTo(UnsignedLong.valueOf(256))<0) + { + _delegate = _oneByteWriter; + } + else + { + _delegate = _eightByteWriter; + } + + _delegate.setValue(ulong); + } + + public boolean isComplete() + { + return _delegate.isComplete(); + } + + public boolean isCacheable() + { + return false; + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedShortWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedShortWriter.java new file mode 100644 index 0000000000..63d8bf0d7b --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedShortWriter.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.UnsignedShort; + +public class UnsignedShortWriter extends FixedTwoWriter +{ + private static final byte FORMAT_CODE = (byte)0x60; + + + @Override + short convertValueToShort(UnsignedShort value) + { + return value.shortValue(); + } + + @Override + byte getFormatCode() + { + return FORMAT_CODE; + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new UnsignedShortWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(UnsignedShort.class, FACTORY); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueHandler.java new file mode 100644 index 0000000000..57351a91d7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueHandler.java @@ -0,0 +1,159 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.transport.AmqpError; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; + +import java.nio.ByteBuffer; +import java.nio.charset.Charset; + +public class ValueHandler implements DescribedTypeConstructorRegistry.Source +{ + private static final byte DESCRIBED_TYPE = (byte)0; + + private final DescribedTypeConstructorRegistry _describedTypeConstructorRegistry; + + + private static final TypeConstructor[][] TYPE_CONSTRUCTORS = + { + {}, + {}, + {}, + {}, + { NullTypeConstructor.getInstance(), BooleanConstructor.getTrueInstance(), + BooleanConstructor.getFalseInstance(), ZeroUIntConstructor.getInstance(), + ZeroULongConstructor.getInstance(), ZeroListConstructor.getInstance() }, + { UByteTypeConstructor.getInstance(), ByteTypeConstructor.getInstance(), + SmallUIntConstructor.getInstance(), SmallULongConstructor.getInstance(), + SmallIntConstructor.getInstance(), SmallLongConstructor.getInstance(), + BooleanConstructor.getByteInstance()}, + { UShortTypeConstructor.getInstance(), ShortTypeConstructor.getInstance() }, + { UIntTypeConstructor.getInstance(), IntTypeConstructor.getInstance(), + FloatTypeConstructor.getInstance(), CharTypeConstructor.getInstance(), + DecimalConstructor.getDecimal32Instance()}, + { ULongTypeConstructor.getInstance(), LongTypeConstructor.getInstance(), + DoubleTypeConstructor.getInstance(), TimestampTypeConstructor.getInstance(), + DecimalConstructor.getDecimal64Instance()}, + { null, null, + null, null, + DecimalConstructor.getDecimal128Instance(), null, + null, null, + UUIDTypeConstructor.getInstance() }, + { BinaryTypeConstructor.getInstance(1), + StringTypeConstructor.getInstance(1, Charset.forName("UTF8")), + StringTypeConstructor.getInstance(1, Charset.forName("UTF16")), + SymbolTypeConstructor.getInstance(1) }, + { BinaryTypeConstructor.getInstance(4), + StringTypeConstructor.getInstance(4, Charset.forName("UTF8")), + StringTypeConstructor.getInstance(4, Charset.forName("UTF16")), + SymbolTypeConstructor.getInstance(4) }, + { CompoundTypeConstructor.getInstance(1, CompoundTypeConstructor.LIST_ASSEMBLER_FACTORY), + CompoundTypeConstructor.getInstance(1, CompoundTypeConstructor.MAP_ASSEMBLER_FACTORY) }, + { CompoundTypeConstructor.getInstance(4, CompoundTypeConstructor.LIST_ASSEMBLER_FACTORY), + CompoundTypeConstructor.getInstance(4, CompoundTypeConstructor.MAP_ASSEMBLER_FACTORY) }, + { + ArrayTypeConstructor.getOneByteSizeTypeConstructor() + }, + { + ArrayTypeConstructor.getFourByteSizeTypeConstructor() + } + }; + + + public ValueHandler(DescribedTypeConstructorRegistry registry) + { + _describedTypeConstructorRegistry = registry; + } + + public Object parse(final ByteBuffer in) throws AmqpErrorException + { + TypeConstructor constructor = readConstructor(in); + return constructor.construct(in, this); + } + + + public TypeConstructor readConstructor(ByteBuffer in) throws AmqpErrorException + { + if(!in.hasRemaining()) + { + throw new AmqpErrorException(AmqpError.DECODE_ERROR, "Insufficient data - expected type, no data remaining"); + } + byte formatCode = in.get(); + + if(formatCode == DESCRIBED_TYPE) + { + Object descriptor = parse(in); + DescribedTypeConstructor describedTypeConstructor = _describedTypeConstructorRegistry.getConstructor(descriptor); + if(describedTypeConstructor==null) + { + describedTypeConstructor=new DefaultDescribedTypeConstructor(descriptor); + } + TypeConstructor typeConstructor = readConstructor(in); + + return describedTypeConstructor.construct(typeConstructor); + + } + else + { + int subCategory = (formatCode >> 4) & 0x0F; + int subtype = formatCode & 0x0F; + + TypeConstructor tc; + try + { + tc = TYPE_CONSTRUCTORS[subCategory][subtype]; + } + catch(IndexOutOfBoundsException e) + { + tc = null; + } + + if(tc == null) + { + throw new AmqpErrorException(ConnectionError.FRAMING_ERROR,"Unknown type format-code 0x%02x", formatCode); + } + + return tc; + } + } + + + + + + @Override + public String toString() + { + return "ValueHandler{" + + ", _describedTypeConstructorRegistry=" + _describedTypeConstructorRegistry + + '}'; + } + + + public DescribedTypeConstructorRegistry getDescribedTypeRegistry() + { + return _describedTypeConstructorRegistry; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueProducingProtocolHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueProducingProtocolHandler.java new file mode 100644 index 0000000000..48db222aa0 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueProducingProtocolHandler.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.transport.Error; + +public interface ValueProducingProtocolHandler extends ProtocolHandler +{ + Object getValue(); + public boolean hasError(); + public Error getError(); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueWriter.java new file mode 100644 index 0000000000..7918397994 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueWriter.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.amqp_1_0.codec; + +import java.nio.ByteBuffer; +import java.util.Map; + +public interface ValueWriter +{ + + + + public static interface Factory + { + ValueWriter newInstance(Registry registry); + } + + public static interface Registry + { + public static interface Source + { + public Registry getDescribedTypeRegistry(); + } + + ValueWriter getValueWriter(V value); + ValueWriter getValueWriter(V value, Map localCache); + ValueWriter register(Class clazz, ValueWriter.Factory writer); + + } + + + int writeToBuffer(ByteBuffer buffer); + + void setValue(T frameBody); + + boolean isComplete(); + + boolean isCacheable(); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthTypeConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthTypeConstructor.java new file mode 100644 index 0000000000..35ce253623 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthTypeConstructor.java @@ -0,0 +1,48 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +import java.nio.ByteBuffer; + +public abstract class VariableWidthTypeConstructor implements TypeConstructor +{ + protected int _size; + + public VariableWidthTypeConstructor(int size) + { + _size = size; + } + + public Object construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException + { + return construct(in, false, handler); + } + + public int getSize() + { + return _size; + } + + public abstract Object construct(ByteBuffer in, boolean isCopy, ValueHandler handler) throws AmqpErrorException; + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthWriter.java new file mode 100644 index 0000000000..93b2b5e6d8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthWriter.java @@ -0,0 +1,169 @@ +/* + * + * 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.amqp_1_0.codec; + +import java.nio.ByteBuffer; + +public abstract class VariableWidthWriter implements ValueWriter +{ + private int _written; + private int _size; + + public int writeToBuffer(ByteBuffer buffer) + { + + int written = _written; + final int length = getLength(); + boolean singleOctetSize = _size == 1; + if(singleOctetSize) + { + switch(written) + { + case 0: + if(buffer.hasRemaining()) + { + buffer.put(getSingleOctetEncodingCode()); + } + else + { + break; + } + case 1: + if(buffer.hasRemaining()) + { + buffer.put((byte)length); + written = 2; + } + else + { + written = 1; + break; + } + default: + + final int toWrite = 2 + length - written; + if(buffer.remaining() >= toWrite) + { + writeBytes(buffer, written-2,toWrite); + written = length + 2; + clearValue(); + } + else + { + final int remaining = buffer.remaining(); + + writeBytes(buffer, written-2, remaining); + written += remaining; + } + + } + } + else + { + + int remaining = buffer.remaining(); + + switch(written) + { + + case 0: + if(buffer.hasRemaining()) + { + buffer.put(getFourOctetEncodingCode()); + remaining--; + written = 1; + } + else + { + break; + } + case 1: + if(remaining >= 4) + { + buffer.putInt(length); + remaining-=4; + written+=4; + } + case 2: + case 3: + if(remaining >= 2 && written <= 3) + { + buffer.putShort((short)((length >> ((3-written)<<3)) & 0xFFFF )); + remaining -= 2; + written += 2; + } + case 4: + if(remaining >=1 && written <=4) + { + buffer.put((byte)((length>> ((4-written)<<3)) & 0xFF )); + written++; + } + + default: + + final int toWrite = 5 + length - written; + if(buffer.remaining() >= toWrite) + { + writeBytes(buffer, written-5,toWrite); + written = length + 5; + clearValue(); + } + else if(buffer.hasRemaining()) + { + written += buffer.remaining(); + writeBytes(buffer, written-5, buffer.remaining()); + } + + } + + } + + _written = written; + return 1 + _size + length; + } + + protected abstract void clearValue(); + + protected abstract boolean hasValue(); + + protected abstract byte getFourOctetEncodingCode(); + + protected abstract byte getSingleOctetEncodingCode(); + + public void setValue(V value) + { + _written = 0; + _size = (getLength() & 0xFFFFFF00) == 0 ? 1 : 4; + } + + protected abstract int getLength(); + + protected abstract void writeBytes(ByteBuffer buf, int offset, int length); + + + public boolean isComplete() + { + return !hasValue() || _written == getLength() + _size + 1; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/WrapperTypeValueWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/WrapperTypeValueWriter.java new file mode 100644 index 0000000000..85a3196f6c --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/WrapperTypeValueWriter.java @@ -0,0 +1,55 @@ +/* + * + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.WrapperType; + +public class WrapperTypeValueWriter extends DelegatingValueWriter +{ + public WrapperTypeValueWriter(final Registry registry) + { + super(registry); + } + + @Override + protected Object getUnderlyingValue(final WrapperType wrapperType) + { + return wrapperType.getValue(); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new WrapperTypeValueWriter(registry); + } + }; + + public boolean isCacheable() + { + return true; + } + + public static void register(Registry registry, Class clazz) + { + registry.register(clazz, FACTORY); + }} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroListConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroListConstructor.java new file mode 100644 index 0000000000..b9d6a50425 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroListConstructor.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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; + +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.List; + +class ZeroListConstructor implements TypeConstructor +{ + private static final ZeroListConstructor INSTANCE = new ZeroListConstructor(); + + ZeroListConstructor() + { + } + + public List construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return Collections.EMPTY_LIST; + } + + public static ZeroListConstructor getInstance() + { + return INSTANCE; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroUIntConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroUIntConstructor.java new file mode 100644 index 0000000000..b3c57ceaf7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroUIntConstructor.java @@ -0,0 +1,45 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; + +import java.nio.ByteBuffer; + +class ZeroUIntConstructor implements TypeConstructor +{ + private static final ZeroUIntConstructor INSTANCE = new ZeroUIntConstructor(); + + ZeroUIntConstructor() + { + } + + public UnsignedInteger construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return UnsignedInteger.ZERO; + } + + public static ZeroUIntConstructor getInstance() + { + return INSTANCE; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroULongConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroULongConstructor.java new file mode 100644 index 0000000000..b2ab2a4158 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroULongConstructor.java @@ -0,0 +1,45 @@ +/* + * 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.amqp_1_0.codec; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.UnsignedLong; + +import java.nio.ByteBuffer; + +class ZeroULongConstructor implements TypeConstructor +{ + private static final ZeroULongConstructor INSTANCE = new ZeroULongConstructor(); + + ZeroULongConstructor() + { + } + + public UnsignedLong construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return UnsignedLong.ZERO; + } + + public static ZeroULongConstructor getInstance() + { + return INSTANCE; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java new file mode 100644 index 0000000000..769fe13d29 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java @@ -0,0 +1,68 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.type.FrameBody; + +import java.nio.ByteBuffer; + +public abstract class AMQFrame +{ + private T _frameBody; + private ByteBuffer _payload; + + AMQFrame(T frameBody) + { + _frameBody = frameBody; + } + + protected AMQFrame(T frameBody, ByteBuffer payload) + { + _frameBody = frameBody; + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + public static TransportFrame createAMQFrame(short channel, FrameBody frameBody) + { + return createAMQFrame(channel, frameBody, null); + } + + public static TransportFrame createAMQFrame(short channel, FrameBody frameBody, ByteBuffer payload) + { + return new TransportFrame(channel, frameBody, payload); + } + + abstract public short getChannel(); + + abstract public byte getFrameType(); + + public T getFrameBody() + { + return _frameBody; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQPProtocolHeaderHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQPProtocolHeaderHandler.java new file mode 100644 index 0000000000..007df77f55 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQPProtocolHeaderHandler.java @@ -0,0 +1,85 @@ +/* + * + * 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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + +import java.nio.ByteBuffer; + +public class AMQPProtocolHeaderHandler implements ProtocolHandler +{ + private ConnectionEndpoint _connection; + private static final byte MAJOR_VERSION = (byte) 1; + private static final byte MINOR_VERSION = (byte) 0; + + enum State { + AWAITING_MAJOR, + AWAITING_MINOR, + AWAITING_REVISION, + ERROR + } + + private State _state = State.AWAITING_MAJOR; + + public AMQPProtocolHeaderHandler(final ConnectionEndpoint connection) + { + _connection = connection; + } + + public ProtocolHandler parse(final ByteBuffer in) + { + while(in.hasRemaining() && _state != State.ERROR) + { + switch(_state) + { + case AWAITING_MAJOR: + _state = in.get() == MAJOR_VERSION ? State.AWAITING_MINOR : State.ERROR; + if(!in.hasRemaining()) + { + break; + } + case AWAITING_MINOR: + _state = in.get() == MINOR_VERSION ? State.AWAITING_MINOR : State.ERROR; + if(!in.hasRemaining()) + { + break; + } + case AWAITING_REVISION: + byte revision = in.get(); + _connection.protocolHeaderReceived(MAJOR_VERSION, MINOR_VERSION, revision); + ProtocolHandler handler = new FrameHandler(_connection); + return handler.parse(in); + } + } + if(_state == State.ERROR) + { + _connection.invalidHeaderReceived(); + } + return this; + + } + + public boolean isDone() + { + return _state != State.ERROR && !_connection.closedForInput(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java new file mode 100644 index 0000000000..78bed8a71e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java @@ -0,0 +1,559 @@ +/* + * + * 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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.codec.FrameWriter; +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; +import org.apache.qpid.amqp_1_0.codec.ProtocolHeaderHandler; +import org.apache.qpid.amqp_1_0.codec.ValueHandler; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.transport.BytesProcessor; +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + +import org.apache.qpid.amqp_1_0.transport.FrameOutputHandler; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.transport.Open; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedShort; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ConnectionHandler +{ + private final ConnectionEndpoint _connection; + private ProtocolHandler _delegate; + + private static final Logger FRAME_LOGGER = Logger.getLogger("FRM"); + private static final Logger RAW_LOGGER = Logger.getLogger("RAW"); + + public ConnectionHandler(final ConnectionEndpoint connection) + { + _connection = connection; + _delegate = new ProtocolHeaderHandler(connection); + } + + + public boolean parse(ByteBuffer in) + { + + while(in.hasRemaining() && !isDone()) + { + _delegate = _delegate.parse(in); + + } + return isDone(); + } + + public boolean isDone() + { + return _delegate.isDone(); + } + + + // ---------------------------------------------------------------- + + public static class FrameOutput implements FrameOutputHandler, FrameSource + { + + private static final ByteBuffer EMPTY_BYTEBUFFER = ByteBuffer.wrap(new byte[0]); + private final BlockingQueue> _queue = new ArrayBlockingQueue>(100); + private ConnectionEndpoint _conn; + + private final AMQFrame _endOfFrameMarker = new AMQFrame(null) + { + @Override public short getChannel() + { + throw new UnsupportedOperationException(); + } + + @Override public byte getFrameType() + { + throw new UnsupportedOperationException(); + } + }; + + private boolean _setForClose; + private boolean _closed; + + public FrameOutput(final ConnectionEndpoint conn) + { + _conn = conn; + } + + public boolean canSend() + { + return _queue.remainingCapacity() != 0; + } + + public void send(AMQFrame frame) + { + send(frame, null); + } + + public void send(final AMQFrame frame, final ByteBuffer payload) + { + synchronized(_conn.getLock()) + { + try + { +// TODO HACK - check frame length + int size = _conn.getDescribedTypeRegistry() + .getValueWriter(frame.getFrameBody()).writeToBuffer(EMPTY_BYTEBUFFER) + 8; + + if(size > _conn.getMaxFrameSize()) + { + throw new OversizeFrameException(frame, size); + } + + while(!_queue.offer(frame)) + { + _conn.getLock().wait(1000L); + + } + _conn.getLock().notifyAll(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + + + public void close() + { + synchronized (_conn.getLock()) + { + if(!_queue.offer(_endOfFrameMarker)) + { + _setForClose = true; + } + _conn.getLock().notifyAll(); + } + } + + public AMQFrame getNextFrame(final boolean wait) + { + synchronized(_conn.getLock()) + { + try + { + AMQFrame frame = null; + while(!closed() && (frame = _queue.poll()) == null && wait) + { + _conn.getLock().wait(); + } + + if(frame == _endOfFrameMarker) + { + _closed = true; + frame = null; + } + else if(_setForClose && frame != null) + { + _setForClose = !_queue.offer(_endOfFrameMarker); + } + + + if(frame != null && FRAME_LOGGER.isLoggable(Level.FINE)) + { + FRAME_LOGGER.fine("SEND[" + _conn.getRemoteAddress() + "|" + frame.getChannel() + "] : " + frame.getFrameBody()); + } + + _conn.getLock().notifyAll(); + + return frame; + } + catch (InterruptedException e) + { + _conn.setClosedForOutput(true); + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + return null; + } + } + } + + public boolean closed() + { + return _closed; + } + } + + public static interface FrameSource + { + AMQFrame getNextFrame(boolean wait); + boolean closed(); + } + + + public static interface BytesSource + { + void getBytes(BytesProcessor processor, boolean wait); + boolean closed(); + } + + public static class FrameToBytesSourceAdapter implements BytesSource + { + + private final FrameSource _frameSource; + private final FrameWriter _writer; + private static final int BUF_SIZE = 1<<16; + private final byte[] _bytes = new byte[BUF_SIZE]; + private final ByteBuffer _buffer = ByteBuffer.wrap(_bytes); + + public FrameToBytesSourceAdapter(final FrameSource frameSource, ValueWriter.Registry registry) + { + _frameSource = frameSource; + _writer = new FrameWriter(registry); + } + + public void getBytes(final BytesProcessor processor, final boolean wait) + { + + AMQFrame frame; + + if(_buffer.position() == 0 && !_frameSource.closed()) + { + if(!_writer.isComplete()) + { + _writer.writeToBuffer(_buffer); + } + + while(_buffer.hasRemaining()) + { + + if((frame = _frameSource.getNextFrame(wait && _buffer.position()==0)) != null) + { + _writer.setValue(frame); + + try + { + _writer.writeToBuffer(_buffer); + } + catch(RuntimeException e) + { + e.printStackTrace(); + throw e; + } + catch(Error e) + { + e.printStackTrace(); + throw e; + } + + + } + else + { + break; + } + } + _buffer.flip(); + } + if(_buffer.limit() != 0) + { + processor.processBytes(_buffer); + if(_buffer.remaining() == 0) + { + _buffer.clear(); + } + } + } + + public boolean closed() + { + return _buffer.position() == 0 && _frameSource.closed(); + } + } + + + public static class HeaderBytesSource implements BytesSource + { + + private final ByteBuffer _buffer; + private ConnectionEndpoint _conn; + + public HeaderBytesSource(ConnectionEndpoint conn, byte... headerBytes) + { + _conn = conn; + _buffer = ByteBuffer.wrap(headerBytes); + } + + public void getBytes(final BytesProcessor processor, final boolean wait) + { + if(!_conn.closedForOutput()) + { + processor.processBytes(_buffer); + } + } + + public boolean closed() + { + return !_conn.closedForOutput() && !_buffer.hasRemaining(); + } + } + + public static class SequentialBytesSource implements BytesSource + { + private Queue _sources = new LinkedList(); + + public SequentialBytesSource(BytesSource... sources) + { + _sources.addAll(Arrays.asList(sources)); + } + + public synchronized void addSource(BytesSource source) + { + _sources.add(source); + } + + public synchronized void getBytes(final BytesProcessor processor, final boolean wait) + { + BytesSource src = _sources.peek(); + while (src != null && src.closed()) + { + _sources.poll(); + src = _sources.peek(); + } + + if(src != null) + { + src.getBytes(processor, wait); + } + } + + public boolean closed() + { + return _sources.isEmpty(); + } + } + + + public static class BytesOutputHandler implements Runnable, BytesProcessor + { + + private final OutputStream _outputStream; + private BytesSource _bytesSource; + private boolean _closed; + private ConnectionEndpoint _conn; + + public BytesOutputHandler(OutputStream outputStream, BytesSource source, ConnectionEndpoint conn) + { + _outputStream = outputStream; + _bytesSource = source; + _conn = conn; + } + + public void run() + { + + final BytesSource bytesSource = _bytesSource; + + while(!(_closed || bytesSource.closed())) + { + _bytesSource.getBytes(this, true); + } + + } + + public void processBytes(final ByteBuffer buf) + { + try + { + if(RAW_LOGGER.isLoggable(Level.FINE)) + { + Binary bin = new Binary(buf.array(),buf.arrayOffset()+buf.position(), buf.limit()-buf.position()); + RAW_LOGGER.fine("SEND["+ _conn.getRemoteAddress() +"] : " + bin.toString()); + } + _outputStream.write(buf.array(),buf.arrayOffset()+buf.position(), buf.limit()-buf.position()); + buf.position(buf.limit()); + } + catch (IOException e) + { + _closed = true; + e.printStackTrace(); //TODO + } + } + } + + + public static class OutputHandler implements Runnable + { + + + + private final OutputStream _outputStream; + private FrameSource _frameSource; + + private static final int BUF_SIZE = 1<<16; + private ValueWriter.Registry _registry; + + + public OutputHandler(OutputStream outputStream, FrameSource source, ValueWriter.Registry registry) + { + _outputStream = outputStream; + _frameSource = source; + _registry = registry; + } + + public void run() + { + int i=0; + + + try + { + + byte[] buffer = new byte[BUF_SIZE]; + ByteBuffer buf = ByteBuffer.wrap(buffer); + + buf.put((byte)'A'); + buf.put((byte)'M'); + buf.put((byte)'Q'); + buf.put((byte)'P'); + buf.put((byte) 0); + buf.put((byte) 1); + buf.put((byte) 0); + buf.put((byte) 0); + + + + final FrameSource frameSource = _frameSource; + + AMQFrame frame; + FrameWriter writer = new FrameWriter(_registry); + + while(!frameSource.closed()) + { + + if(!writer.isComplete()) + { + writer.writeToBuffer(buf); + } + + while(buf.hasRemaining()) + { + + if((frame = frameSource.getNextFrame(buf.position()==0)) != null) + { + writer.setValue(frame); + + int size = writer.writeToBuffer(buf); + + } + else + { + break; + } + } + + if(buf.limit() != 0) + { + _outputStream.write(buffer,0, buf.position()); + buf.clear(); + } + } + + } + catch (IOException e) + { + e.printStackTrace(); + } + + } + } + + public static void main(String[] args) throws AmqpErrorException + { + byte[] buffer = new byte[76]; + ByteBuffer buf = ByteBuffer.wrap(buffer); + AMQPDescribedTypeRegistry registry = AMQPDescribedTypeRegistry.newInstance() + .registerTransportLayer() + .registerMessagingLayer() + .registerTransactionLayer(); + + Open open = new Open(); + // Open(container_id="venture", channel_max=10, hostname="foo", offered_capabilities=[Symbol("one"), Symbol("two"), Symbol("three")]) + open.setContainerId("venture"); + open.setChannelMax(UnsignedShort.valueOf((short) 10)); + open.setHostname("foo"); + open.setOfferedCapabilities(new Symbol[] {Symbol.valueOf("one"),Symbol.valueOf("two"),Symbol.valueOf("three")}); + + ValueWriter writer = registry.getValueWriter(open); + + System.out.println("------ Encode (time in ms for 1 million opens)"); + Long myLong = Long.valueOf(32); + ValueWriter writer2 = registry.getValueWriter(myLong); + Double myDouble = Double.valueOf(3.14159265359); + ValueWriter writer3 = registry.getValueWriter(myDouble); + for(int n = 0; n < 1/*00*/; n++) + { + long startTime = System.currentTimeMillis(); + for(int i = 1/*000000*/; i !=0; i--) + { + buf.position(0); + writer.setValue(open); + writer.writeToBuffer(buf); + writer2.setValue(myLong); + writer.writeToBuffer(buf); + writer3.setValue(myDouble); + writer3.writeToBuffer(buf); + + + } + long midTime = System.currentTimeMillis(); + System.out.println((midTime - startTime)); + + } + + + ValueHandler handler = new ValueHandler(registry); + System.out.println("------ Decode (time in ms for 1 million opens)"); + for(int n = 0; n < 100; n++) + { + long startTime = System.currentTimeMillis(); + for(int i = 1000000; i !=0; i--) + { + buf.flip(); + handler.parse(buf); + handler.parse(buf); + handler.parse(buf); + + } + long midTime = System.currentTimeMillis(); + System.out.println((midTime - startTime)); + } + + + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java new file mode 100644 index 0000000000..76a28d23e9 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java @@ -0,0 +1,329 @@ +/* + * + * 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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.codec.BinaryWriter; +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; +import org.apache.qpid.amqp_1_0.codec.ValueHandler; +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.ErrorCondition; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + +import java.nio.ByteBuffer; +import java.util.Formatter; + +public class FrameHandler implements ProtocolHandler +{ + private ConnectionEndpoint _connection; + private ValueHandler _typeHandler; + + enum State { + SIZE_0, + SIZE_1, + SIZE_2, + SIZE_3, + PRE_PARSE, + BUFFERING, + PARSING, + ERROR + } + + private State _state = State.SIZE_0; + private int _size; + + private ByteBuffer _buffer; + + + + public FrameHandler(final ConnectionEndpoint connection) + { + _connection = connection; + _typeHandler = new ValueHandler(connection.getDescribedTypeRegistry()); + + } + + public ProtocolHandler parse(ByteBuffer in) + { + try + { + Error frameParsingError = null; + int size = _size; + State state = _state; + ByteBuffer oldIn = null; + + while(in.hasRemaining() && state != State.ERROR) + { + + final int remaining = in.remaining(); + if(remaining == 0) + { + return this; + } + + + switch(state) + { + case SIZE_0: + if(remaining >= 4) + { + size = in.getInt(); + state = State.PRE_PARSE; + break; + } + else + { + size = (in.get() << 24) & 0xFF000000; + if(!in.hasRemaining()) + { + state = State.SIZE_1; + break; + } + } + case SIZE_1: + size |= (in.get() << 16) & 0xFF0000; + if(!in.hasRemaining()) + { + state = State.SIZE_2; + break; + } + case SIZE_2: + size |= (in.get() << 8) & 0xFF00; + if(!in.hasRemaining()) + { + state = State.SIZE_3; + break; + } + case SIZE_3: + size |= in.get() & 0xFF; + state = State.PRE_PARSE; + + case PRE_PARSE: + + if(size < 8) + { + frameParsingError = createFramingError("specified frame size %d smaller than minimum frame header size %d", _size, 8); + state = State.ERROR; + break; + } + + else if(size > _connection.getMaxFrameSize()) + { + frameParsingError = createFramingError("specified frame size %d larger than maximum frame header size %d", size, _connection.getMaxFrameSize()); + state = State.ERROR; + break; + } + + if(in.remaining() < size-4) + { + _buffer = ByteBuffer.allocate(size-4); + _buffer.put(in); + state = State.BUFFERING; + break; + } + case BUFFERING: + if(_buffer != null) + { + if(in.remaining() < _buffer.remaining()) + { + _buffer.put(in); + break; + } + else + { + ByteBuffer dup = in.duplicate(); + dup.limit(dup.position()+_buffer.remaining()); + int i = _buffer.remaining(); + int d = dup.remaining(); + in.position(in.position()+_buffer.remaining()); + _buffer.put(dup); + oldIn = in; + _buffer.flip(); + in = _buffer; + state = State.PARSING; + } + } + + case PARSING: + + int dataOffset = (in.get() << 2) & 0x3FF; + + if(dataOffset < 8) + { + frameParsingError = createFramingError("specified frame data offset %d smaller than minimum frame header size %d", dataOffset, 8); + state = State.ERROR; + break; + } + else if(dataOffset > size) + { + frameParsingError = createFramingError("specified frame data offset %d larger than the frame size %d", dataOffset, _size); + state = State.ERROR; + break; + } + + // type + + int type = in.get() & 0xFF; + int channel = in.getShort() & 0xFF; + + if(type != 0 && type != 1) + { + frameParsingError = createFramingError("unknown frame type: %d", type); + state = State.ERROR; + break; + } + + // channel + + /*if(channel > _connection.getChannelMax()) + { + frameParsingError = createError(AmqpError.DECODE_ERROR, + "frame received on invalid channel %d above channel-max %d", + channel, _connection.getChannelMax()); + + state = State.ERROR; + } +*/ + // ext header + if(dataOffset!=8) + { + in.position(in.position()+dataOffset-8); + } + + // oldIn null iff not working on duplicated buffer + if(oldIn == null) + { + oldIn = in; + in = in.duplicate(); + final int endPos = in.position() + size - dataOffset; + in.limit(endPos); + oldIn.position(endPos); + + } + + int inPos = in.position(); + int inLimit = in.limit(); + // PARSE HERE + try + { + Object val = _typeHandler.parse(in); + + if(in.hasRemaining()) + { + if(val instanceof Transfer) + { + ByteBuffer buf = ByteBuffer.allocate(in.remaining()); + buf.put(in); + buf.flip(); + ((Transfer)val).setPayload(buf); + } + } + + _connection.receive((short)channel,val); + reset(); + in = oldIn; + oldIn = null; + _buffer = null; + state = State.SIZE_0; + break; + + + } + catch (AmqpErrorException ex) + { + state = State.ERROR; + frameParsingError = ex.getError(); + } + catch (RuntimeException e) + { + in.position(inPos); + in.limit(inLimit); + System.err.println(toHex(in)); + throw e; + } + } + + } + + _state = state; + _size = size; + + if(_state == State.ERROR) + { + _connection.handleError(frameParsingError); + } + return this; + } + catch(RuntimeException e) + { + e.printStackTrace(); + throw e; + } + } + + private static String toHex(ByteBuffer in) + { + Formatter formatter = new Formatter(); + int count = 0; + while(in.hasRemaining()) + { + formatter.format("%02x ", in.get() & 0xFF); + if(count++ == 16) + { + formatter.format("\n"); + count = 0; + } + + } + return formatter.toString(); + } + + private Error createFramingError(String description, Object... args) + { + return createError(ConnectionError.FRAMING_ERROR, description, args); + } + + private Error createError(final ErrorCondition framingError, + final String description, + final Object... args) + { + Error error = new Error(); + error.setCondition(framingError); + Formatter formatter = new Formatter(); + error.setDescription(formatter.format(description, args).toString()); + return error; + } + + + private void reset() + { + _size = 0; + _state = State.SIZE_0; + } + + + public boolean isDone() + { + return _state == State.ERROR || _connection.closedForInput(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameParsingError.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameParsingError.java new file mode 100644 index 0000000000..e8bd462b87 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameParsingError.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.amqp_1_0.framing; + +public enum FrameParsingError +{ + UNDERSIZED_FRAME_HEADER, + OVERSIZED_FRAME_HEADER, + DATA_OFFSET_IN_HEADER, + DATA_OFFSET_TOO_LARGE, + UNKNOWN_FRAME_TYPE, + CHANNEL_ID_BEYOND_MAX, + SPARE_OCTETS_IN_FRAME_BODY, + INSUFFICIENT_OCTETS_IN_FRAME_BODY, + UNKNOWN_TYPE_CODE, UNPARSABLE_TYPE; +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameTypeHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameTypeHandler.java new file mode 100644 index 0000000000..6d680c8b02 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameTypeHandler.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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; + +public interface FrameTypeHandler extends ProtocolHandler +{ + void setExtHeaderRemaining(int size); + + void setBodySize(int size); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/OversizeFrameException.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/OversizeFrameException.java new file mode 100644 index 0000000000..37897d9cb5 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/OversizeFrameException.java @@ -0,0 +1,42 @@ +/* + * 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.amqp_1_0.framing; + +public class OversizeFrameException extends RuntimeException +{ + private final AMQFrame _frame; + private int _size; + + public OversizeFrameException(final AMQFrame frame, final int size) + { + _frame = frame; + _size = size; + } + + public AMQFrame getFrame() + { + return _frame; + } + + public int getSize() + { + return _size; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrame.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrame.java new file mode 100644 index 0000000000..4155b605c4 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrame.java @@ -0,0 +1,42 @@ +/* + * 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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.type.SaslFrameBody; + +public final class SASLFrame extends AMQFrame +{ + + public SASLFrame(SaslFrameBody frameBody) + { + super(frameBody); + } + + @Override public short getChannel() + { + return (short)0; + } + + @Override public byte getFrameType() + { + return (byte)1; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrameHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrameHandler.java new file mode 100644 index 0000000000..be7023bfdc --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrameHandler.java @@ -0,0 +1,311 @@ +/* + * 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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; +import org.apache.qpid.amqp_1_0.codec.ProtocolHeaderHandler; +import org.apache.qpid.amqp_1_0.codec.ValueHandler; +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.ErrorCondition; +import org.apache.qpid.amqp_1_0.type.transport.ConnectionError; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.nio.ByteBuffer; +import java.util.Formatter; + +public class SASLFrameHandler implements ProtocolHandler +{ + private ConnectionEndpoint _connection; + private ValueHandler _typeHandler; + + enum State { + SIZE_0, + SIZE_1, + SIZE_2, + SIZE_3, + PRE_PARSE, + BUFFERING, + PARSING, + ERROR + } + + private State _state = State.SIZE_0; + private int _size; + + private ByteBuffer _buffer; + + + + public SASLFrameHandler(final ConnectionEndpoint connection) + { + _connection = connection; + _typeHandler = new ValueHandler(connection.getDescribedTypeRegistry()); + + } + + public ProtocolHandler parse(ByteBuffer in) + { + try + { + Error frameParsingError = null; + int size = _size; + State state = _state; + ByteBuffer oldIn = null; + + while(in.hasRemaining() && !_connection.isSASLComplete() && state != State.ERROR) + { + + final int remaining = in.remaining(); + if(remaining == 0) + { + return this; + } + + + switch(state) + { + case SIZE_0: + if(remaining >= 4) + { + size = in.getInt(); + state = State.PRE_PARSE; + break; + } + else + { + size = (in.get() << 24) & 0xFF000000; + if(!in.hasRemaining()) + { + state = State.SIZE_1; + break; + } + } + case SIZE_1: + size |= (in.get() << 16) & 0xFF0000; + if(!in.hasRemaining()) + { + state = State.SIZE_2; + break; + } + case SIZE_2: + size |= (in.get() << 8) & 0xFF00; + if(!in.hasRemaining()) + { + state = State.SIZE_3; + break; + } + case SIZE_3: + size |= in.get() & 0xFF; + state = State.PRE_PARSE; + + case PRE_PARSE: + + if(size < 8) + { + frameParsingError = createFramingError("specified frame size %d smaller than minimum frame header size %d", _size, 8); + state = State.ERROR; + break; + } + + else if(size > _connection.getMaxFrameSize()) + { + frameParsingError = createFramingError("specified frame size %d larger than maximum frame header size %d", size, _connection.getMaxFrameSize()); + state = State.ERROR; + break; + } + + if(in.remaining() < size-4) + { + _buffer = ByteBuffer.allocate(size-4); + _buffer.put(in); + state = State.BUFFERING; + break; + } + case BUFFERING: + if(_buffer != null) + { + if(in.remaining() < _buffer.remaining()) + { + _buffer.put(in); + break; + } + else + { + ByteBuffer dup = in.duplicate(); + dup.limit(dup.position()+_buffer.remaining()); + int i = _buffer.remaining(); + int d = dup.remaining(); + in.position(in.position()+_buffer.remaining()); + _buffer.put(dup); + oldIn = in; + _buffer.flip(); + in = _buffer; + state = State.PARSING; + } + } + + case PARSING: + + int dataOffset = (in.get() << 2) & 0x3FF; + + if(dataOffset < 8) + { + frameParsingError = createFramingError("specified frame data offset %d smaller than minimum frame header size %d", dataOffset, 8); + state = State.ERROR; + break; + } + else if(dataOffset > size) + { + frameParsingError = createFramingError("specified frame data offset %d larger than the frame size %d", dataOffset, _size); + state = State.ERROR; + break; + } + + // type + + int type = in.get() & 0xFF; + int channel = in.getShort() & 0xFF; + + if(type != 0 && type != 1) + { + frameParsingError = createFramingError("unknown frame type: %d", type); + state = State.ERROR; + break; + } + + if(type != 1) + { + System.err.println("Wrong frame type for SASL Frame"); + } + + // channel + + /*if(channel > _connection.getChannelMax()) + { + frameParsingError = createError(AmqpError.DECODE_ERROR, + "frame received on invalid channel %d above channel-max %d", + channel, _connection.getChannelMax()); + + state = State.ERROR; + } +*/ + // ext header + if(dataOffset!=8) + { + in.position(in.position()+dataOffset-8); + } + + // oldIn null iff not working on duplicated buffer + if(oldIn == null) + { + oldIn = in; + in = in.duplicate(); + final int endPos = in.position() + size - dataOffset; + in.limit(endPos); + oldIn.position(endPos); + + } + + + // PARSE HERE + try + { + Object val = _typeHandler.parse(in); + + if(in.hasRemaining()) + { + state = State.ERROR; + frameParsingError = createFramingError("Frame length %d larger than contained frame body %s.", size, val); + + } + else + { + _connection.receive((short)channel,val); + reset(); + in = oldIn; + oldIn = null; + _buffer = null; + state = State.SIZE_0; + break; + } + + + } + catch (AmqpErrorException ex) + { + state = State.ERROR; + frameParsingError = ex.getError(); + } + } + + } + + _state = state; + _size = size; + + if(_state == State.ERROR) + { + _connection.handleError(frameParsingError); + } + if(_connection.isSASLComplete()) + { + return new ProtocolHeaderHandler(_connection); + } + else + { + return this; + } + } + catch(RuntimeException e) + { + e.printStackTrace(); + throw e; + } + } + + private Error createFramingError(String description, Object... args) + { + return createError(ConnectionError.FRAMING_ERROR, description, args); + } + + private Error createError(final ErrorCondition framingError, + final String description, + final Object... args) + { + Error error = new Error(); + error.setCondition(framingError); + Formatter formatter = new Formatter(); + error.setDescription(formatter.format(description, args).toString()); + return error; + } + + + private void reset() + { + _size = 0; + _state = State.SIZE_0; + } + + + public boolean isDone() + { + return _state == State.ERROR || _connection.closedForInput(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLProtocolHeaderHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLProtocolHeaderHandler.java new file mode 100644 index 0000000000..4ab90df92a --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLProtocolHeaderHandler.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.qpid.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + +import java.nio.ByteBuffer; + +public class SASLProtocolHeaderHandler implements ProtocolHandler +{ + private ConnectionEndpoint _connection; + private static final byte MAJOR_VERSION = (byte) 1; + private static final byte MINOR_VERSION = (byte) 0; + + enum State { + AWAITING_MAJOR, + AWAITING_MINOR, + AWAITING_REVISION, + ERROR + } + + private State _state = State.AWAITING_MAJOR; + + + + public SASLProtocolHeaderHandler(final ConnectionEndpoint connection) + { + _connection = connection; + } + + public ProtocolHandler parse(final ByteBuffer in) + { + while(in.hasRemaining() && _state != State.ERROR) + { + switch(_state) + { + case AWAITING_MAJOR: + _state = in.get() == MAJOR_VERSION ? State.AWAITING_MINOR : State.ERROR; + if(!in.hasRemaining()) + { + break; + } + case AWAITING_MINOR: + _state = in.get() == MINOR_VERSION ? State.AWAITING_MINOR : State.ERROR; + if(!in.hasRemaining()) + { + break; + } + case AWAITING_REVISION: + byte revision = in.get(); + _connection.protocolHeaderReceived(MAJOR_VERSION, MINOR_VERSION, revision); + ProtocolHandler handler = new SASLFrameHandler(_connection); + return handler.parse(in); + } + } + if(_state == State.ERROR) + { + _connection.invalidHeaderReceived(); + } + return this; + + } + + public boolean isDone() + { + return _state != State.ERROR && !_connection.closedForInput(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/TransportFrame.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/TransportFrame.java new file mode 100644 index 0000000000..b66d36ebeb --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/TransportFrame.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.amqp_1_0.framing; + +import org.apache.qpid.amqp_1_0.type.FrameBody; + +import java.nio.ByteBuffer; + +public final class TransportFrame extends AMQFrame +{ + + private final short _channel; + + TransportFrame(short channel, FrameBody frameBody) + { + super(frameBody); + _channel = channel; + } + + public TransportFrame(short channel, FrameBody frameBody, ByteBuffer payload) + { + super(frameBody, payload); + _channel = channel; + } + + @Override public short getChannel() + { + return _channel; + } + + @Override public byte getFrameType() + { + return (byte)0; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/MessageAttributes.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/MessageAttributes.java new file mode 100644 index 0000000000..7c1c62388d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/MessageAttributes.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.amqp_1_0.messaging; + +import org.apache.qpid.amqp_1_0.type.Symbol; + +import java.util.Map; + +public interface MessageAttributes extends Map +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoder.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoder.java new file mode 100644 index 0000000000..f72d5848b6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoder.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.amqp_1_0.messaging; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Section; + +import java.nio.ByteBuffer; +import java.util.List; + + +public interface SectionDecoder +{ + + public List
parseAll(ByteBuffer buf) throws AmqpErrorException; + public Section readSection(ByteBuffer buf) throws AmqpErrorException; + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoderImpl.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoderImpl.java new file mode 100644 index 0000000000..ed2b0094f9 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoderImpl.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. + */ + +package org.apache.qpid.amqp_1_0.messaging; + +import org.apache.qpid.amqp_1_0.codec.ValueHandler; + +import org.apache.qpid.amqp_1_0.type.AmqpErrorException; +import org.apache.qpid.amqp_1_0.type.Section; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class SectionDecoderImpl implements SectionDecoder +{ + + private ValueHandler _valueHandler; + + + public SectionDecoderImpl(final AMQPDescribedTypeRegistry describedTypeRegistry) + { + _valueHandler = new ValueHandler(describedTypeRegistry); + } + + public List
parseAll(ByteBuffer buf) throws AmqpErrorException + { + + List
obj = new ArrayList
(); + while(buf.hasRemaining()) + { + Section section = (Section) _valueHandler.parse(buf); + obj.add(section); + } + + return obj; + } + + public Section readSection(ByteBuffer buf) throws AmqpErrorException + { + return (Section) _valueHandler.parse(buf); + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoder.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoder.java new file mode 100644 index 0000000000..bcb9112d14 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoder.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.amqp_1_0.messaging; + +import org.apache.qpid.amqp_1_0.type.Binary; + + +public interface SectionEncoder +{ + void reset(); + + Binary getEncoding(); + + void encodeObject(Object obj); + + void encodeRaw(byte[] data); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoderImpl.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoderImpl.java new file mode 100644 index 0000000000..9636dea4b7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoderImpl.java @@ -0,0 +1,111 @@ +/* + * 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.amqp_1_0.messaging; + +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class SectionEncoderImpl implements SectionEncoder +{ + private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.wrap(new byte[0]); + private ValueWriter.Registry _registry; + + private int _totalSize = 0; + + private List _output = new ArrayList(); + private static final int DEFAULT_BUFFER_SIZE = 64 * 1024; + private ByteBuffer _current; + + public SectionEncoderImpl(final AMQPDescribedTypeRegistry describedTypeRegistry) + { + _registry = describedTypeRegistry; + reset(); + } + + public void reset() + { + _totalSize = 0; + _output.clear(); + _current = null; + + } + + public Binary getEncoding() + { + byte[] data = new byte[_totalSize]; + int offset = 0; + for(byte[] src : _output) + { + int length = src.length; + System.arraycopy(src, 0, data, offset, _totalSize - offset < length ? _totalSize - offset : length); + offset+= length; + } + return new Binary(data); + } + + public void encodeObject(Object obj) + { + final ValueWriter valueWriter = _registry.getValueWriter(obj); + valueWriter.setValue(obj); + int size = valueWriter.writeToBuffer(EMPTY_BYTE_BUFFER); + + byte[] data = new byte[size]; + _current = ByteBuffer.wrap(data); + valueWriter.writeToBuffer(_current); + _output.add(data); + + + _totalSize += size; + + + } + + public void encodeRaw(byte[] data) + { + if(_current == null) + { + byte[] buf = new byte[data.length]; + _current = ByteBuffer.wrap(buf); + _output.add(buf); + } + int remaining = _current.remaining(); + int length = data.length; + + if(remaining < length) + { + _current.put(data,0,remaining); + byte[] dst = new byte[length-remaining]; + _output.add(dst); + _current = ByteBuffer.wrap(dst).put(data,remaining,length-remaining); + } + else + { + _current.put(data); + } + _totalSize += data.length; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPFrameTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPFrameTransport.java new file mode 100644 index 0000000000..7cb10b923f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPFrameTransport.java @@ -0,0 +1,179 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.framing.AMQFrame; +import org.apache.qpid.amqp_1_0.type.FrameBody; + +import java.nio.ByteBuffer; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + + +public class AMQPFrameTransport implements FrameTransport>, FrameOutputHandler +{ + private final Object _inputLock = new Object(); + private final Object _outputLock = new Object(); + + private volatile boolean _inputOpen = true; + private volatile boolean _outputOpen = true; + + private final ConnectionEndpoint _endpoint; + private final BlockingQueue> _queue = new ArrayBlockingQueue>(100); + private StateChangeListener _inputListener; + private StateChangeListener _outputListener; + + + public AMQPFrameTransport(final ConnectionEndpoint endpoint) + { + _endpoint = endpoint; + + _endpoint.setFrameOutputHandler(this); + } + + public boolean isOpenForInput() + { + return _inputOpen; + } + + public void closeForInput() + { + synchronized(_inputLock) + { + _inputOpen = false; + _inputLock.notifyAll(); + } + } + + public void processIncomingFrame(final AMQFrame frame) + { + frame.getFrameBody().invoke(frame.getChannel(), _endpoint); + } + + + public boolean canSend() + { + return _queue.remainingCapacity() != 0; + } + + public void send(AMQFrame frame) + { + send(frame, null); + } + + + public void send(final AMQFrame frame, final ByteBuffer payload) + { + synchronized(_endpoint.getLock()) + { + boolean empty = _queue.isEmpty(); + try + { + + while(!_queue.offer(frame)) + { + _endpoint.getLock().wait(1000L); + + } + if(empty && _outputListener != null) + { + _outputListener.onStateChange(true); + } + + _endpoint.getLock().notifyAll(); + } + catch (InterruptedException e) + { + + } + } + } + + public void close() + { + synchronized (_endpoint.getLock()) + { + _endpoint.getLock().notifyAll(); + } + } + + public AMQFrame getNextFrame() + { + synchronized(_endpoint.getLock()) + { + AMQFrame frame = null; + if(isOpenForOutput()) + { + frame = _queue.poll(); + } + return frame; + } + } + + public void closeForOutput() + { + synchronized (_outputLock) + { + _outputOpen = false; + _outputLock.notifyAll(); + } + } + + public boolean isOpenForOutput() + { + return _outputOpen; + } + + public ValueWriter.Registry getRegistry() + { + return _endpoint.getDescribedTypeRegistry(); + } + + public void setInputStateChangeListener(final StateChangeListener listener) + { + _inputListener = listener; + } + + public void setOutputStateChangeListener(final StateChangeListener listener) + { + _outputListener = listener; + } + + public void setVersion(final byte major, final byte minor, final byte revision) + { + + } + + public byte getMajorVersion() + { + return _endpoint.getMajorVersion(); + } + + public byte getMinorVersion() + { + return _endpoint.getMinorVersion(); + } + + public byte getRevision() + { + return _endpoint.getRevision(); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPTransport.java new file mode 100644 index 0000000000..8327cf6f26 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPTransport.java @@ -0,0 +1,170 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.codec.FrameWriter; +import org.apache.qpid.amqp_1_0.framing.AMQFrame; +import org.apache.qpid.amqp_1_0.framing.TransportFrame; +import org.apache.qpid.amqp_1_0.type.FrameBody; + +import java.nio.ByteBuffer; + +public class AMQPTransport implements BytesTransport +{ + private volatile boolean _inputOpen = true; + private volatile boolean _outputOpen = true; + + private static final int INPUT_BUFFER_SIZE = 1 << 16; + private static final int OUTPUT_BUFFER_SIZE = 1 << 16; + + + private final CircularBytesBuffer _inputBuffer = new CircularBytesBuffer(INPUT_BUFFER_SIZE); + private TransportFrame _currentInputFrame; + private boolean _readingFrames; + + + private final CircularBytesBuffer _outputBuffer = new CircularBytesBuffer(OUTPUT_BUFFER_SIZE); + + private AMQFrame _currentOutputFrame; + + + private AMQPFrameTransport _frameTransport; + + private FrameWriter _frameWriter; + + private final BytesProcessor _frameWriterProcessor = new BytesProcessor() + { + public void processBytes(final ByteBuffer buf) + { + _frameWriter.writeToBuffer(buf); + + if(_frameWriter.isComplete()) + { + _currentOutputFrame = null; + } + } + }; + + private StateChangeListener _inputListener; + private StateChangeListener _outputListener; + + + public AMQPTransport(AMQPFrameTransport frameTransport) + { + _frameTransport = frameTransport; + _frameWriter = new FrameWriter(_frameTransport.getRegistry()); + _outputBuffer.put( ByteBuffer.wrap( new byte[] { (byte) 'A', + (byte) 'M', + (byte) 'Q', + (byte) 'P', + (byte) 0, + _frameTransport.getMajorVersion(), + _frameTransport.getMajorVersion(), + _frameTransport.getRevision(), + } ) ); + + + } + + public boolean isOpenForInput() + { + return _inputOpen; + } + + public void inputClosed() + { + _inputOpen = false; + } + + public void processBytes(final ByteBuffer buf) + { + _inputBuffer.put(buf); + + if(!_readingFrames) + { + if(_inputBuffer.size()>=8) + { + final byte[] incomingHeader = new byte[8]; + _inputBuffer.get(new BytesProcessor() + { + public void processBytes(final ByteBuffer buf) + { + buf.get(incomingHeader); + } + }); + _frameTransport.setVersion(incomingHeader[5], incomingHeader[6], incomingHeader[7]); + _readingFrames = true; + } + } + else + { + + } + + + //To change body of implemented methods use File | Settings | File Templates. + } + + public void setInputStateChangeListener(final StateChangeListener listener) + { + _inputListener = listener; + _frameTransport.setInputStateChangeListener(listener); + } + + public void getNextBytes(final BytesProcessor processor) + { + // First try to fill the buffer as much as possible with frames + while(!_outputBuffer.isFull()) + { + if(_currentOutputFrame == null) + { + _currentOutputFrame = _frameTransport.getNextFrame(); + _frameWriter.setValue(_currentOutputFrame); + } + + if(_currentOutputFrame == null) + { + break; + } + + + _outputBuffer.put(_frameWriterProcessor); + + + + } + + } + + public void outputClosed() + { + _outputOpen = false; + } + + public boolean isOpenForOutput() + { + return _outputOpen; + } + + public void setOutputStateChangeListener(final StateChangeListener listener) + { + _outputListener = listener; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesProcessor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesProcessor.java new file mode 100644 index 0000000000..d26eda302f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesProcessor.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.amqp_1_0.transport; + +import java.nio.ByteBuffer; + +public interface BytesProcessor +{ + void processBytes(ByteBuffer buf); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesTransport.java new file mode 100644 index 0000000000..6932e7628b --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesTransport.java @@ -0,0 +1,38 @@ +/* + * 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.amqp_1_0.transport; + + +import java.nio.ByteBuffer; + +public interface BytesTransport extends BytesProcessor +{ + + boolean isOpenForInput(); + void inputClosed(); + void processBytes(ByteBuffer buf); + void setInputStateChangeListener(StateChangeListener listener); + + void getNextBytes(BytesProcessor processor); + void outputClosed(); + boolean isOpenForOutput(); + void setOutputStateChangeListener(StateChangeListener listener); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CallbackHandlerSource.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CallbackHandlerSource.java new file mode 100644 index 0000000000..604279a21f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CallbackHandlerSource.java @@ -0,0 +1,28 @@ +/* + * 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.amqp_1_0.transport; + + +import javax.security.auth.callback.CallbackHandler; + +public interface CallbackHandlerSource +{ + CallbackHandler getHandler(String mechanism); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CircularBytesBuffer.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CircularBytesBuffer.java new file mode 100644 index 0000000000..e71eedd1e1 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CircularBytesBuffer.java @@ -0,0 +1,174 @@ +/* + * 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.amqp_1_0.transport; + +import java.nio.ByteBuffer; + +public class CircularBytesBuffer +{ + + private final byte[] _buffer; + private final int _mask; + private final ByteBuffer _inputBuffer; + private final ByteBuffer _outputBuffer; + + private volatile int _start; + private volatile int _size; + + public CircularBytesBuffer(int size) + { + size = calculateSize(size); + _buffer = new byte[size]; + _mask = size - 1; + _inputBuffer = ByteBuffer.wrap(_buffer); + _outputBuffer = ByteBuffer.wrap(_buffer); + + } + + + public int size() + { + return _size; + } + + public boolean isFull() + { + return _size == _buffer.length; + } + + public boolean isEmpty() + { + return _size == 0; + } + + public void put(ByteBuffer buffer) + { + if(!isFull()) + { + int start; + int size; + + synchronized(this) + { + start = _start; + size = _size; + } + + int pos = (start + size) & _mask; + int length = ((_buffer.length - pos) > size ? start : _buffer.length) - pos; + int remaining = length > buffer.remaining() ? buffer.remaining() : length; + buffer.get(_buffer, pos, remaining); + + synchronized(this) + { + _size += remaining; + } + + // We may still have space left if we have to wrap from the end to the start of the buffer + if(buffer.hasRemaining()) + { + put(buffer); + } + } + } + + public synchronized void put(BytesProcessor processor) + { + if(!isFull()) + { + int start; + int size; + + synchronized(this) + { + start = _start; + size = _size; + } + int pos = (start + size) & _mask; + int length = ((_buffer.length - pos) > size ? start : _buffer.length) - pos; + _outputBuffer.position(pos); + _outputBuffer.limit(pos+length); + processor.processBytes(_outputBuffer); + + synchronized (this) + { + _size += length - _outputBuffer.remaining(); + } + + if(_outputBuffer.remaining() == 0) + { + put(processor); + } + } + } + + public synchronized void get(BytesProcessor processor) + { + if(!isEmpty()) + { + int start; + int size; + + synchronized(this) + { + start = _start; + size = _size; + } + + + int length = start + size > _buffer.length ? _buffer.length - start : size; + + _inputBuffer.position(start); + _inputBuffer.limit(start+length); + processor.processBytes(_inputBuffer); + final int consumed = length - _inputBuffer.remaining(); + + synchronized(this) + { + _start += consumed; + _size -= consumed; + } + + if(!_inputBuffer.hasRemaining()) + { + get(processor); + } + } + } + + private int calculateSize(int size) + { + int n = 0; + int s = size; + do + { + s>>=1; + n++; + } + while(s > 0); + + s = 1 << n; + if(s < size) + { + s<<= 1; + } + return s; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java new file mode 100644 index 0000000000..4ad8b4196e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java @@ -0,0 +1,934 @@ +/* + * + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.framing.AMQFrame; +import org.apache.qpid.amqp_1_0.framing.SASLFrame; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.security.SaslChallenge; +import org.apache.qpid.amqp_1_0.type.security.SaslCode; +import org.apache.qpid.amqp_1_0.type.security.SaslInit; +import org.apache.qpid.amqp_1_0.type.security.SaslMechanisms; +import org.apache.qpid.amqp_1_0.type.security.SaslOutcome; +import org.apache.qpid.amqp_1_0.type.security.SaslResponse; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; + + +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; +import javax.security.sasl.SaslServerFactory; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.nio.charset.Charset; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.logging.Level; +import java.util.logging.Logger; + + +public class ConnectionEndpoint implements DescribedTypeConstructorRegistry.Source, ValueWriter.Registry.Source, + ErrorHandler, SASLEndpoint + +{ + private static final short CONNECTION_CONTROL_CHANNEL = (short) 0; + private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.wrap(new byte[0]); + + private final Container _container; + private Principal _user; + + private static final short DEFAULT_CHANNEL_MAX = 255; + private static final int DEFAULT_MAX_FRAME = Integer.getInteger("amqp.max_frame_size",1<<15); + + + private ConnectionState _state = ConnectionState.UNOPENED; + private short _channelMax; + private int _maxFrameSize = 4096; + private String _remoteContainerId; + + private SocketAddress _remoteAddress; + + // positioned by the *outgoing* channel + private SessionEndpoint[] _sendingSessions = new SessionEndpoint[DEFAULT_CHANNEL_MAX+1]; + + // positioned by the *incoming* channel + private SessionEndpoint[] _receivingSessions = new SessionEndpoint[DEFAULT_CHANNEL_MAX+1]; + private boolean _closedForInput; + private boolean _closedForOutput; + + private AMQPDescribedTypeRegistry _describedTypeRegistry = AMQPDescribedTypeRegistry.newInstance() + .registerTransportLayer() + .registerMessagingLayer() + .registerTransactionLayer() + .registerSecurityLayer(); + + private FrameOutputHandler _frameOutputHandler; + + private byte _majorVersion; + private byte _minorVersion; + private byte _revision; + private UnsignedInteger _handleMax = UnsignedInteger.MAX_VALUE; + private ConnectionEventListener _connectionEventListener = ConnectionEventListener.DEFAULT; + private String _password; + private final boolean _requiresSASLClient; + private final boolean _requiresSASLServer; + + + private FrameOutputHandler _saslFrameOutput; + + private boolean _saslComplete; + + private UnsignedInteger _desiredMaxFrameSize = UnsignedInteger.valueOf(DEFAULT_MAX_FRAME); + private Runnable _onSaslCompleteTask; + + private CallbackHandlerSource _callbackHandlersource; + private SaslServer _saslServer; + private boolean _authenticated; + private String _remoteHostname; + + public ConnectionEndpoint(Container container, CallbackHandlerSource cbs) + { + _container = container; + _callbackHandlersource = cbs; + _requiresSASLClient = false; + _requiresSASLServer = cbs != null; + } + + public ConnectionEndpoint(Container container, Principal user, String password) + { + _container = container; + _user = user; + _password = password; + _requiresSASLClient = user != null; + _requiresSASLServer = false; + } + + + public synchronized void open() + { + if(_requiresSASLClient) + { + synchronized (getLock()) + { + while(!_saslComplete) + { + try + { + getLock().wait(); + } + catch (InterruptedException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + } + } + if(!_authenticated) + { + throw new RuntimeException("Could not connect - authentication error"); + } + } + if(_state == ConnectionState.UNOPENED) + { + sendOpen(DEFAULT_CHANNEL_MAX, DEFAULT_MAX_FRAME); + _state = ConnectionState.AWAITING_OPEN; + } + } + + public void setFrameOutputHandler(final FrameOutputHandler frameOutputHandler) + { + _frameOutputHandler = frameOutputHandler; + } + + public synchronized SessionEndpoint createSession(String name) + { + // todo assert connection state + SessionEndpoint endpoint = new SessionEndpoint(this); + short channel = getFirstFreeChannel(); + if(channel != -1) + { + _sendingSessions[channel] = endpoint; + endpoint.setSendingChannel(channel); + Begin begin = new Begin(); + begin.setNextOutgoingId(endpoint.getNextOutgoingId()); + begin.setOutgoingWindow(endpoint.getOutgoingWindowSize()); + begin.setIncomingWindow(endpoint.getIncomingWindowSize()); + + begin.setHandleMax(_handleMax); + send(channel, begin); + + } + else + { + // todo error + } + return endpoint; + } + + + public Container getContainer() + { + return _container; + } + + public Principal getUser() + { + return _user; + } + + public short getChannelMax() + { + return _channelMax; + } + + public int getMaxFrameSize() + { + return _maxFrameSize; + } + + public String getRemoteContainerId() + { + return _remoteContainerId; + } + + private void sendOpen(final short channelMax, final int maxFrameSize) + { + Open open = new Open(); + + open.setChannelMax(UnsignedShort.valueOf(DEFAULT_CHANNEL_MAX)); + open.setContainerId(_container.getId()); + open.setMaxFrameSize(getDesiredMaxFrameSize()); + open.setHostname(getRemoteHostname()); + + + send(CONNECTION_CONTROL_CHANNEL, open); + } + + public UnsignedInteger getDesiredMaxFrameSize() + { + return _desiredMaxFrameSize; + } + + + public void setDesiredMaxFrameSize(UnsignedInteger size) + { + _desiredMaxFrameSize = size; + } + + + + + private void closeSender() + { + setClosedForOutput(true); + _frameOutputHandler.close(); + } + + + short getFirstFreeChannel() + { + for(int i = 0; i<_sendingSessions.length;i++) + { + if(_sendingSessions[i]==null) + { + return (short) i; + } + } + return -1; + } + + private SessionEndpoint getSession(final short channel) + { + // TODO assert existence, check channel state + return _receivingSessions[channel]; + } + + + public synchronized void receiveOpen(short channel, Open open) + { + + _channelMax = open.getChannelMax() == null ? DEFAULT_CHANNEL_MAX + : open.getChannelMax().shortValue() < DEFAULT_CHANNEL_MAX + ? DEFAULT_CHANNEL_MAX + : open.getChannelMax().shortValue(); + + UnsignedInteger remoteDesiredMaxFrameSize = open.getMaxFrameSize() == null ? UnsignedInteger.valueOf(DEFAULT_MAX_FRAME) : open.getMaxFrameSize(); + + _maxFrameSize = (remoteDesiredMaxFrameSize.compareTo(_desiredMaxFrameSize) < 0 ? remoteDesiredMaxFrameSize : _desiredMaxFrameSize).intValue(); + + _remoteContainerId = open.getContainerId(); + + switch(_state) + { + case UNOPENED: + sendOpen(_channelMax, _maxFrameSize); + case AWAITING_OPEN: + _state = ConnectionState.OPEN; + default: + // TODO bad stuff (connection already open) + + } + /*if(_state == ConnectionState.AWAITING_OPEN) + { + _state = ConnectionState.OPEN; + } +*/ + } + + public synchronized void receiveClose(short channel, Close close) + { + setClosedForInput(true); + _connectionEventListener.closeReceived(); + switch(_state) + { + case UNOPENED: + case AWAITING_OPEN: + Error error = new Error(); + error.setCondition(ConnectionError.CONNECTION_FORCED); + error.setDescription("Connection close sent before connection was opened"); + connectionError(error); + break; + case OPEN: + sendClose(new Close()); + break; + case CLOSE_SENT: + default: + } + } + + protected synchronized void connectionError(Error error) + { + Close close = new Close(); + close.setError(error); + switch(_state) + { + case UNOPENED: + _state = ConnectionState.CLOSED; + break; + case AWAITING_OPEN: + case OPEN: + sendClose(close); + _state = ConnectionState.CLOSE_SENT; + case CLOSE_SENT: + case CLOSED: + // already sent our close - too late to do anything more + break; + default: + // TODO Unknown state + } + } + + public synchronized void inputClosed() + { + if(!_closedForInput) + { + _closedForInput = true; + for(int i = 0; i < _receivingSessions.length; i++) + { + if(_receivingSessions[i] != null) + { + _receivingSessions[i].end(); + _receivingSessions[i]=null; + + } + } + } + notifyAll(); + } + + private void sendClose(Close closeToSend) + { + send(CONNECTION_CONTROL_CHANNEL, closeToSend); + closeSender(); + } + + private synchronized void setClosedForInput(boolean closed) + { + _closedForInput = closed; + + notifyAll(); + } + + public synchronized void receiveBegin(short channel, Begin begin) + { + short myChannelId; + + + + if(begin.getRemoteChannel() != null) + { + myChannelId = begin.getRemoteChannel().shortValue(); + SessionEndpoint endpoint; + try + { + endpoint = _sendingSessions[myChannelId]; + } + catch(IndexOutOfBoundsException e) + { + final Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("BEGIN received on channel " + channel + " with given remote-channel " + + begin.getRemoteChannel() + " which is outside the valid range of 0 to " + + _channelMax + "."); + connectionError(error); + return; + } + if(endpoint != null) + { + if(_receivingSessions[channel] == null) + { + _receivingSessions[channel] = endpoint; + endpoint.setReceivingChannel(channel); + endpoint.setNextIncomingId(begin.getNextOutgoingId()); + endpoint.setOutgoingSessionCredit(begin.getIncomingWindow()); + } + else + { + final Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("BEGIN received on channel " + channel + " which is already in use."); + connectionError(error); + } + } + else + { + final Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("BEGIN received on channel " + channel + " with given remote-channel " + + begin.getRemoteChannel() + " which is not known as a begun session."); + connectionError(error); + } + + + } + else // Peer requesting session creation + { + + myChannelId = getFirstFreeChannel(); + if(myChannelId == -1) + { + // close any half open channel + myChannelId = getFirstFreeChannel(); + + } + + if(_receivingSessions[channel] == null) + { + SessionEndpoint endpoint = new SessionEndpoint(this,begin); + + _receivingSessions[channel] = endpoint; + _sendingSessions[myChannelId] = endpoint; + + Begin beginToSend = new Begin(); + + endpoint.setReceivingChannel(channel); + endpoint.setSendingChannel(myChannelId); + beginToSend.setRemoteChannel(UnsignedShort.valueOf(channel)); + beginToSend.setNextOutgoingId(endpoint.getNextOutgoingId()); + beginToSend.setOutgoingWindow(endpoint.getOutgoingWindowSize()); + beginToSend.setIncomingWindow(endpoint.getIncomingWindowSize()); + send(myChannelId, beginToSend); + + _connectionEventListener.remoteSessionCreation(endpoint); + } + else + { + final Error error = new Error(); + error.setCondition(ConnectionError.FRAMING_ERROR); + error.setDescription("BEGIN received on channel " + channel + " which is already in use."); + connectionError(error); + } + + } + + + + } + + + + public synchronized void receiveEnd(short channel, End end) + { + SessionEndpoint endpoint = _receivingSessions[channel]; + if(endpoint != null) + { + _receivingSessions[channel] = null; + + endpoint.end(end); + } + else + { + // TODO error + } + + } + + + public synchronized void sendEnd(short channel, End end) + { + send(channel, end); + _sendingSessions[channel] = null; + } + + public synchronized void receiveAttach(short channel, Attach attach) + { + SessionEndpoint endPoint = getSession(channel); + endPoint.receiveAttach(attach); + } + + + public synchronized void receiveDetach(short channel, Detach detach) + { + SessionEndpoint endPoint = getSession(channel); + endPoint.receiveDetach(detach); + } + + public synchronized void receiveTransfer(short channel, Transfer transfer) + { + SessionEndpoint endPoint = getSession(channel); + endPoint.receiveTransfer(transfer); + } + + public synchronized void receiveDisposition(short channel, Disposition disposition) + { + SessionEndpoint endPoint = getSession(channel); + endPoint.receiveDisposition(disposition); + } + + public synchronized void receiveFlow(short channel, Flow flow) + { + SessionEndpoint endPoint = getSession(channel); + endPoint.receiveFlow(flow); + } + + + public synchronized void send(short channel, FrameBody body) + { + send(channel, body, null); + } + + + public synchronized int send(short channel, FrameBody body, ByteBuffer payload) + { + if(!_closedForOutput) + { + ValueWriter writer = _describedTypeRegistry.getValueWriter(body); + int size = writer.writeToBuffer(EMPTY_BYTE_BUFFER); + ByteBuffer payloadDup = payload == null ? null : payload.duplicate(); + int payloadSent = getMaxFrameSize() - (size + 9); + if(payloadSent < (payload == null ? 0 : payload.remaining())) + { + + if(body instanceof Transfer) + { + ((Transfer)body).setMore(Boolean.TRUE); + } + + writer = _describedTypeRegistry.getValueWriter(body); + size = writer.writeToBuffer(EMPTY_BYTE_BUFFER); + payloadSent = getMaxFrameSize() - (size + 9); + + try + { + payloadDup.limit(payloadDup.position()+payloadSent); + } + catch(NullPointerException npe) + { + throw npe; + } + } + else + { + payloadSent = payload == null ? 0 : payload.remaining(); + } + _frameOutputHandler.send(AMQFrame.createAMQFrame(channel, body, payloadDup)); + return payloadSent; + } + else + { + return -1; + } + } + + + + public void invalidHeaderReceived() + { + // TODO + _closedForInput = true; + } + + public synchronized boolean closedForInput() + { + return _closedForInput; + } + + public synchronized void protocolHeaderReceived(final byte major, final byte minorVersion, final byte revision) + { + if(_requiresSASLServer && _state != ConnectionState.UNOPENED) + { + // TODO - bad stuff + } + + _majorVersion = major; + _minorVersion = minorVersion; + _revision = revision; + } + + public synchronized void handleError(final Error error) + { + if(!closedForOutput()) + { + Close close = new Close(); + close.setError(error); + send((short) 0, close); + } + _closedForInput = true; + } + + private final Logger _logger = Logger.getLogger("FRM"); + + public synchronized void receive(final short channel, final Object frame) + { + if(_logger.isLoggable(Level.FINE)) + { + _logger.fine("RECV["+ _remoteAddress + "|"+channel+"] : " + frame); + } + if(frame instanceof FrameBody) + { + ((FrameBody)frame).invoke(channel, this); + } + else if(frame instanceof SaslFrameBody) + { + ((SaslFrameBody)frame).invoke(this); + } + } + + public AMQPDescribedTypeRegistry getDescribedTypeRegistry() + { + return _describedTypeRegistry; + } + + public synchronized void setClosedForOutput(boolean b) + { + _closedForOutput = true; + notifyAll(); + } + + public synchronized boolean closedForOutput() + { + return _closedForOutput; + } + + + public Object getLock() + { + return this; + } + + public synchronized void close() + { + switch(_state) + { + case AWAITING_OPEN: + case OPEN: + Close closeToSend = new Close(); + sendClose(closeToSend); + _state = ConnectionState.CLOSE_SENT; + break; + case CLOSE_SENT: + default: + } + + } + + public void setConnectionEventListener(final ConnectionEventListener connectionEventListener) + { + _connectionEventListener = connectionEventListener; + } + + public ConnectionEventListener getConnectionEventListener() + { + return _connectionEventListener; + } + + public byte getMinorVersion() + { + return _minorVersion; + } + + public byte getRevision() + { + return _revision; + } + + public byte getMajorVersion() + { + return _majorVersion; + } + + public void receiveSaslInit(final SaslInit saslInit) + { + Symbol mechanism = saslInit.getMechanism(); + final Binary initialResponse = saslInit.getInitialResponse(); + byte[] response = initialResponse == null ? new byte[0] : initialResponse.getArray(); + + + try + { + _saslServer = Sasl.createSaslServer(mechanism.toString(), + "AMQP", + "localhost", + null, + _callbackHandlersource.getHandler(mechanism.toString())); + + // Process response from the client + byte[] challenge = _saslServer.evaluateResponse(response != null ? response : new byte[0]); + + if (_saslServer.isComplete()) + { + SaslOutcome outcome = new SaslOutcome(); + + outcome.setCode(SaslCode.OK); + _saslFrameOutput.send(new SASLFrame(outcome), null); + synchronized (getLock()) + { + _saslComplete = true; + _authenticated = true; + getLock().notifyAll(); + } + + if(_onSaslCompleteTask != null) + { + _onSaslCompleteTask.run(); + } + + } + else + { + SaslChallenge challengeBody = new SaslChallenge(); + challengeBody.setChallenge(new Binary(challenge)); + _saslFrameOutput.send(new SASLFrame(challengeBody), null); + + } + } + catch (SaslException e) + { + SaslOutcome outcome = new SaslOutcome(); + + outcome.setCode(SaslCode.AUTH); + _saslFrameOutput.send(new SASLFrame(outcome), null); + synchronized (getLock()) + { + _saslComplete = true; + _authenticated = false; + getLock().notifyAll(); + } + if(_onSaslCompleteTask != null) + { + _onSaslCompleteTask.run(); + } + + } + } + + public void receiveSaslMechanisms(final SaslMechanisms saslMechanisms) + { + if(Arrays.asList(saslMechanisms.getSaslServerMechanisms()).contains(Symbol.valueOf("PLAIN"))) + { + SaslInit init = new SaslInit(); + init.setMechanism(Symbol.valueOf("PLAIN")); + init.setHostname(_remoteHostname); + byte[] usernameBytes = _user.getName().getBytes(Charset.forName("UTF-8")); + byte[] passwordBytes = _password.getBytes(Charset.forName("UTF-8")); + byte[] initResponse = new byte[usernameBytes.length+passwordBytes.length+2]; + System.arraycopy(usernameBytes,0,initResponse,1,usernameBytes.length); + System.arraycopy(passwordBytes,0,initResponse,usernameBytes.length+2,passwordBytes.length); + init.setInitialResponse(new Binary(initResponse)); + _saslFrameOutput.send(new SASLFrame(init),null); + } + } + + public void receiveSaslChallenge(final SaslChallenge saslChallenge) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void receiveSaslResponse(final SaslResponse saslResponse) + { + final Binary responseBinary = saslResponse.getResponse(); + byte[] response = responseBinary == null ? new byte[0] : responseBinary.getArray(); + + + try + { + + // Process response from the client + byte[] challenge = _saslServer.evaluateResponse(response != null ? response : new byte[0]); + + if (_saslServer.isComplete()) + { + SaslOutcome outcome = new SaslOutcome(); + + outcome.setCode(SaslCode.OK); + _saslFrameOutput.send(new SASLFrame(outcome),null); + synchronized (getLock()) + { + _saslComplete = true; + _authenticated = true; + getLock().notifyAll(); + } + if(_onSaslCompleteTask != null) + { + _onSaslCompleteTask.run(); + } + + } + else + { + SaslChallenge challengeBody = new SaslChallenge(); + challengeBody.setChallenge(new Binary(challenge)); + _saslFrameOutput.send(new SASLFrame(challengeBody), null); + + } + } + catch (SaslException e) + { + SaslOutcome outcome = new SaslOutcome(); + + outcome.setCode(SaslCode.AUTH); + _saslFrameOutput.send(new SASLFrame(outcome),null); + synchronized (getLock()) + { + _saslComplete = true; + _authenticated = false; + getLock().notifyAll(); + } + if(_onSaslCompleteTask != null) + { + _onSaslCompleteTask.run(); + } + + } + } + + public void receiveSaslOutcome(final SaslOutcome saslOutcome) + { + if(saslOutcome.getCode() == SaslCode.OK) + { + _saslFrameOutput.close(); + synchronized (getLock()) + { + _saslComplete = true; + _authenticated = true; + getLock().notifyAll(); + } + if(_onSaslCompleteTask != null) + { + _onSaslCompleteTask.run(); + } + } + else + { + synchronized (getLock()) + { + _saslComplete = true; + _authenticated = false; + getLock().notifyAll(); + } + setClosedForInput(true); + _saslFrameOutput.close(); + } + } + + public boolean requiresSASL() + { + return _requiresSASLClient || _requiresSASLServer; + } + + public void setSaslFrameOutput(final FrameOutputHandler saslFrameOutput) + { + _saslFrameOutput = saslFrameOutput; + } + + public void setOnSaslComplete(Runnable task) + { + _onSaslCompleteTask = task; + + } + + public boolean isAuthenticated() + { + return _authenticated; + } + + public void initiateSASL() + { + SaslMechanisms mechanisms = new SaslMechanisms(); + final Enumeration saslServerFactories = Sasl.getSaslServerFactories(); + + SaslServerFactory f; + ArrayList mechanismsList = new ArrayList(); + while(saslServerFactories.hasMoreElements()) + { + f = saslServerFactories.nextElement(); + final String[] mechanismNames = f.getMechanismNames(null); + for(String name : mechanismNames) + { + mechanismsList.add(Symbol.valueOf(name)); + } + + } + mechanisms.setSaslServerMechanisms(mechanismsList.toArray(new Symbol[mechanismsList.size()])); + _saslFrameOutput.send(new SASLFrame(mechanisms), null); + } + + public boolean isSASLComplete() + { + return _saslComplete; + } + + public SocketAddress getRemoteAddress() + { + return _remoteAddress; + } + + public void setRemoteAddress(SocketAddress remoteAddress) + { + _remoteAddress = remoteAddress; + } + + public String getRemoteHostname() + { + return _remoteHostname; + } + + public void setRemoteHostname(final String remoteHostname) + { + _remoteHostname = remoteHostname; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEventListener.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEventListener.java new file mode 100644 index 0000000000..17163598d2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEventListener.java @@ -0,0 +1,43 @@ +/* + * 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.amqp_1_0.transport; + +public interface ConnectionEventListener +{ + class DefaultConnectionEventListener implements ConnectionEventListener + { + public void remoteSessionCreation(final SessionEndpoint endpoint) + { + endpoint.end(); + } + + public void closeReceived() + { + + } + } + + public static final ConnectionEventListener DEFAULT = new DefaultConnectionEventListener(); + + void remoteSessionCreation(SessionEndpoint endpoint); + + public void closeReceived(); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionState.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionState.java new file mode 100644 index 0000000000..a46526b58f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionState.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.amqp_1_0.transport; + +public enum ConnectionState +{ + UNOPENED, + AWAITING_OPEN, + OPEN, + CLOSE_SENT, + CLOSED +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java new file mode 100644 index 0000000000..2e7e2fe2ea --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java @@ -0,0 +1,79 @@ +/* + * + * 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.amqp_1_0.transport; + +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.atomic.AtomicInteger; + +public class Container +{ + + private static final AtomicInteger CONTAINER_ID = new AtomicInteger(0); + + private String _id; + + public Container() + { + String hostname; + try + { + InetAddress addr = InetAddress.getLocalHost(); + + + // Get hostname + hostname = addr.getHostName(); + } + catch (UnknownHostException e) + { + hostname="127.0.0.1"; + } + + String pid; + String hackForPid = ManagementFactory.getRuntimeMXBean().getName(); + if(hackForPid != null && hackForPid.contains("@")) + { + pid = hackForPid.split("@")[0]; + } + else + { + pid = "unknown"; + } + + _id = hostname + '(' + pid + ')' + ':' + CONTAINER_ID.incrementAndGet(); + + } + + + public Container(String id) + { + _id = id; + } + + public String getId() + { + return _id; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java new file mode 100644 index 0000000000..4135199045 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java @@ -0,0 +1,95 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + +import java.util.ArrayList; +import java.util.List; + +public class Delivery +{ + private boolean _complete; + private boolean _settled; + private final List _transfers = new ArrayList(1); + private final UnsignedInteger _deliveryId; + private final Binary _deliveryTag; + private final LinkEndpoint _linkEndpoint; + + public Delivery(Transfer transfer, final LinkEndpoint endpoint) + { + _settled = Boolean.TRUE.equals(transfer.getSettled()); + _deliveryId = transfer.getDeliveryId(); + _deliveryTag = transfer.getDeliveryTag(); + _linkEndpoint = endpoint; + addTransfer(transfer); + } + + public boolean isComplete() + { + return _complete; + } + + public void setComplete(final boolean complete) + { + _complete = complete; + } + + public boolean isSettled() + { + return _settled; + } + + public void setSettled(final boolean settled) + { + _settled = settled; + } + + public void addTransfer(Transfer transfer) + { + _transfers.add(transfer); + if(Boolean.TRUE.equals(transfer.getAborted()) || !Boolean.TRUE.equals(transfer.getMore())) + { + setComplete(true); + } + } + + public List getTransfers() + { + return _transfers; + } + + public UnsignedInteger getDeliveryId() + { + return _deliveryId; + } + + public LinkEndpoint getLinkEndpoint() + { + return _linkEndpoint; + } + + public Binary getDeliveryTag() + { + return _deliveryTag; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/DeliveryStateHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/DeliveryStateHandler.java new file mode 100644 index 0000000000..95a16d375f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/DeliveryStateHandler.java @@ -0,0 +1,28 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.DeliveryState; + +public interface DeliveryStateHandler +{ + public void handle(final Binary deliveryTag, final DeliveryState state, final Boolean settled); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ErrorHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ErrorHandler.java new file mode 100644 index 0000000000..e3bd37b225 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ErrorHandler.java @@ -0,0 +1,9 @@ +package org.apache.qpid.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.transport.*; + + +public interface ErrorHandler +{ + void handleError(org.apache.qpid.amqp_1_0.type.transport.Error error); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameOutputHandler.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameOutputHandler.java new file mode 100644 index 0000000000..77933702ba --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameOutputHandler.java @@ -0,0 +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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.framing.AMQFrame; + +import java.nio.ByteBuffer; + +public interface FrameOutputHandler +{ + boolean canSend(); + + void send(AMQFrame frame); + void send(AMQFrame frame, ByteBuffer payload); + + void close(); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameTransport.java new file mode 100644 index 0000000000..0f9cc8f5e8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameTransport.java @@ -0,0 +1,37 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.framing.AMQFrame; + +public interface FrameTransport +{ + boolean isOpenForInput(); + void closeForInput(); + void processIncomingFrame(T frame); + + T getNextFrame(); + void closeForOutput(); + boolean isOpenForOutput(); + + void setInputStateChangeListener(StateChangeListener listener); + void setOutputStateChangeListener(StateChangeListener listener); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java new file mode 100644 index 0000000000..60c1427e10 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java @@ -0,0 +1,542 @@ +/* + * + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public abstract class LinkEndpoint +{ + + private T _linkEventListener; + private DeliveryStateHandler _deliveryStateHandler; + private Object _flowTransactionId; + private SenderSettleMode _sendingSettlementMode; + private ReceiverSettleMode _receivingSettlementMode; + private Map _initialUnsettledMap; + private Map _localUnsettled; + private UnsignedInteger _lastSentCreditLimit; + + + private enum State + { + DETACHED, + ATTACH_SENT, + ATTACH_RECVD, + ATTACHED, + DETACH_SENT, + DETACH_RECVD + }; + + private final String _name; + + private SessionEndpoint _session; + + + private volatile State _state = State.DETACHED; + + private Source _source; + private Target _target; + private UnsignedInteger _deliveryCount; + private UnsignedInteger _linkCredit; + private UnsignedInteger _available; + private Boolean _drain; + private UnsignedInteger _localHandle; + private UnsignedLong _maxMessageSize; + + private Map _unsettledTransfers = new HashMap(); + + LinkEndpoint(final SessionEndpoint sessionEndpoint, String name, Map unsettled) + { + _name = name; + _session = sessionEndpoint; + _linkCredit = UnsignedInteger.valueOf(0); + _drain = Boolean.FALSE; + _localUnsettled = unsettled; + + } + + LinkEndpoint(final SessionEndpoint sessionEndpoint,final Attach attach) + { + _session = sessionEndpoint; + + _name = attach.getName(); + _initialUnsettledMap = attach.getUnsettled(); + + _state = State.ATTACH_RECVD; + } + + public String getName() + { + return _name; + } + + public abstract Role getRole(); + + public Source getSource() + { + return _source; + } + + public void setSource(final Source source) + { + _source = source; + } + + public Target getTarget() + { + return _target; + } + + public void setTarget(final Target target) + { + _target = target; + } + + public void setDeliveryCount(final UnsignedInteger deliveryCount) + { + _deliveryCount = deliveryCount; + } + + public void setLinkCredit(final UnsignedInteger linkCredit) + { + _linkCredit = linkCredit; + } + + public void setAvailable(final UnsignedInteger available) + { + _available = available; + } + + public void setDrain(final Boolean drain) + { + _drain = drain; + } + + public UnsignedInteger getDeliveryCount() + { + return _deliveryCount; + } + + public UnsignedInteger getAvailable() + { + return _available; + } + + public Boolean getDrain() + { + return _drain; + } + + public UnsignedInteger getLinkCredit() + { + return _linkCredit; + } + + public void remoteDetached(Detach detach) + { + synchronized (getLock()) + { + switch(_state) + { + case DETACH_SENT: + _state = State.DETACHED; + break; + case ATTACHED: + _state = State.DETACH_RECVD; + _linkEventListener.remoteDetached(this, detach); + break; + } + getLock().notifyAll(); + } + } + + public void receiveTransfer(final Transfer transfer, final Delivery delivery) + { + // TODO + } + + public void settledByPeer(final Binary deliveryTag) + { + // TODO + } + + public void receiveFlow(final Flow flow) + { + } + + public void addUnsettled(final Delivery unsettled) + { + synchronized(getLock()) + { + _unsettledTransfers.put(unsettled.getDeliveryTag(), unsettled); + getLock().notifyAll(); + } + } + + public void receiveDeliveryState(final Delivery unsettled, + final DeliveryState state, + final Boolean settled) + { + // TODO + synchronized(getLock()) + { + if(_deliveryStateHandler != null) + { + _deliveryStateHandler.handle(unsettled.getDeliveryTag(), state, settled); + } + + if(settled) + { + settle(unsettled.getDeliveryTag()); + } + + getLock().notifyAll(); + } + + } + + public void settle(final Binary deliveryTag) + { + Delivery delivery = _unsettledTransfers.remove(deliveryTag); + if(delivery != null) + { + getSession().settle(getRole(),delivery.getDeliveryId()); + } + + } + + public int getUnsettledCount() + { + synchronized(getLock()) + { + return _unsettledTransfers.size(); + } + } + + public void setLocalHandle(final UnsignedInteger localHandle) + { + _localHandle = localHandle; + } + + public void receiveAttach(final Attach attach) + { + synchronized(getLock()) + { + switch(_state) + { + case ATTACH_SENT: + { + + _state = State.ATTACHED; + getLock().notifyAll(); + + _initialUnsettledMap = attach.getUnsettled(); + /* TODO - don't yet handle: + + attach.getUnsettled(); + attach.getProperties(); + attach.getDurable(); + attach.getExpiryPolicy(); + attach.getTimeout(); + */ + + break; + } + + case DETACHED: + { + _state = State.ATTACHED; + getLock().notifyAll(); + } + + + } + + if(attach.getRole() == Role.SENDER) + { + _source = attach.getSource(); + } + else + { + _target = attach.getTarget(); + } + + if(getRole() == Role.SENDER) + { + _maxMessageSize = attach.getMaxMessageSize(); + } + + } + } + + public synchronized boolean isAttached() + { + return _state == State.ATTACHED; + } + + public synchronized boolean isDetached() + { + return _state == State.DETACHED; + } + + public SessionEndpoint getSession() + { + return _session; + } + + public UnsignedInteger getLocalHandle() + { + return _localHandle; + } + + public Object getLock() + { + return _session.getLock(); + } + + public void attach() + { + synchronized(getLock()) + { + Attach attachToSend = new Attach(); + attachToSend.setName(getName()); + attachToSend.setRole(getRole()); + attachToSend.setHandle(getLocalHandle()); + attachToSend.setSource(getSource()); + attachToSend.setTarget(getTarget()); + attachToSend.setSndSettleMode(getSendingSettlementMode()); + attachToSend.setRcvSettleMode(getReceivingSettlementMode()); + attachToSend.setUnsettled(_localUnsettled); + + if(getRole() == Role.SENDER) + { + attachToSend.setInitialDeliveryCount(_deliveryCount); + } + + switch(_state) + { + case DETACHED: + _state = State.ATTACH_SENT; + break; + case ATTACH_RECVD: + _state = State.ATTACHED; + break; + default: + // TODO ERROR + } + + getSession().sendAttach(attachToSend); + + getLock().notifyAll(); + + } + + } + + + public void detach() + { + detach(null, false); + } + + public void close() + { + detach(null, true); + } + + public void close(Error error) + { + detach(error, true); + } + + public void detach(Error error) + { + detach(error, false); + } + + private void detach(Error error, boolean close) + { + synchronized(getLock()) + { + //TODO + switch(_state) + { + case ATTACHED: + _state = State.DETACH_SENT; + break; + case DETACH_RECVD: + _state = State.DETACHED; + break; + default: + return; + } + + Detach detach = new Detach(); + detach.setHandle(getLocalHandle()); + if(close) + detach.setClosed(close); + detach.setError(error); + + getSession().sendDetach(detach); + + getLock().notifyAll(); + } + + } + + + + + public void setTransactionId(final Object txnId) + { + _flowTransactionId = txnId; + } + + public void sendFlowConditional() + { + if(_lastSentCreditLimit != null) + { + UnsignedInteger clientsCredit = _lastSentCreditLimit.subtract(_deliveryCount); + int i = _linkCredit.subtract(clientsCredit).compareTo(clientsCredit); + if(i >=0) + { + sendFlow(_flowTransactionId != null); + } + else + { + getSession().sendFlowConditional(); + } + } + else + { + sendFlow(_flowTransactionId != null); + } + } + + + public void sendFlow() + { + sendFlow(_flowTransactionId != null); + } + + public void sendFlow(boolean setTransactionId) + { + if(_state == State.ATTACHED || _state == State.ATTACH_SENT) + { + Flow flow = new Flow(); + flow.setLinkCredit(_linkCredit); + flow.setDeliveryCount(_deliveryCount); + _lastSentCreditLimit = _linkCredit.add(_deliveryCount); + flow.setAvailable(_available); + flow.setDrain(_drain); + if(setTransactionId) + { + flow.setProperties(Collections.singletonMap(Symbol.valueOf("txn-id"), _flowTransactionId)); + } + flow.setHandle(getLocalHandle()); + getSession().sendFlow(flow); + } + } + + public T getLinkEventListener() + { + return _linkEventListener; + } + + public void setLinkEventListener(final T linkEventListener) + { + synchronized(getLock()) + { + _linkEventListener = linkEventListener; + } + } + + public DeliveryStateHandler getDeliveryStateHandler() + { + return _deliveryStateHandler; + } + + public void setDeliveryStateHandler(final DeliveryStateHandler deliveryStateHandler) + { + synchronized(getLock()) + { + _deliveryStateHandler = deliveryStateHandler; + } + } + + public void setSendingSettlementMode(SenderSettleMode sendingSettlementMode) + { + _sendingSettlementMode = sendingSettlementMode; + } + + public SenderSettleMode getSendingSettlementMode() + { + return _sendingSettlementMode; + } + + public ReceiverSettleMode getReceivingSettlementMode() + { + return _receivingSettlementMode; + } + + public void setReceivingSettlementMode(ReceiverSettleMode receivingSettlementMode) + { + _receivingSettlementMode = receivingSettlementMode; + } + + public Map getInitialUnsettledMap() + { + return _initialUnsettledMap; + } + + + public abstract void flowStateChanged(); + + public void setLocalUnsettled(Map unsettled) + { + _localUnsettled = unsettled; + } + + @Override public String toString() + { + return "LinkEndpoint{" + + "_name='" + _name + '\'' + + ", _session=" + _session + + ", _state=" + _state + + ", _role=" + getRole() + + ", _source=" + _source + + ", _target=" + _target + + ", _transferCount=" + _deliveryCount + + ", _linkCredit=" + _linkCredit + + ", _available=" + _available + + ", _drain=" + _drain + + ", _localHandle=" + _localHandle + + ", _maxMessageSize=" + _maxMessageSize + + '}'; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEventListener.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEventListener.java new file mode 100644 index 0000000000..c56a227e31 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEventListener.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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.transport.Detach; + +public interface LinkEventListener +{ + + + void remoteDetached(final LinkEndpoint endpoint, Detach detach); + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Node.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Node.java new file mode 100644 index 0000000000..fb2270b51b --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Node.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.amqp_1_0.transport; + +public class Node +{ + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ProtocolHeaderTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ProtocolHeaderTransport.java new file mode 100644 index 0000000000..f9abbeb832 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ProtocolHeaderTransport.java @@ -0,0 +1,134 @@ +/* + * 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.amqp_1_0.transport; + + +import org.apache.qpid.amqp_1_0.type.Binary; + +import java.nio.ByteBuffer; +import java.util.Map; + +public class ProtocolHeaderTransport implements BytesTransport +{ + private final Object _inputLock = new Object(); + private final Object _outputLock = new Object(); + + private volatile boolean _inputOpen; + private volatile boolean _outputOpen; + + private final Map _headersMap; + + private BytesTransport _delegate; + private ByteBuffer _bytesToSend; + + private byte[] _header = new byte[8]; + private int _received; + private ByteBuffer _outputBuffer; + + public ProtocolHeaderTransport(Map validHeaders) + { + _headersMap = validHeaders; + + // if only one valid header then we can send, else we have to wait + } + + public boolean isOpenForInput() + { + return _inputOpen; + } + + public void inputClosed() + { + synchronized(_inputLock) + { + _inputOpen = false; + _inputLock.notifyAll(); + } + } + + public void processBytes(final ByteBuffer buf) + { + if(_delegate != null) + { + _delegate.processBytes(buf); + } + else + { + + while( _received < 8 && buf.hasRemaining()) + { + _header[_received++] = buf.get(); + } + if(_received == 8) + { + Binary header = new Binary(_header); + _delegate = _headersMap.get(header); + if(_delegate != null) + { + _delegate.processBytes(ByteBuffer.wrap(_header)); + _delegate.processBytes(buf); + } + else + { + inputClosed(); + _outputBuffer = _headersMap.keySet().iterator().next().asByteBuffer(); + } + } + } + } + + public void setInputStateChangeListener(final StateChangeListener listener) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + + public void getNextBytes(final BytesProcessor processor) + { + if(_bytesToSend != null && _bytesToSend.hasRemaining()) + { + processor.processBytes(_bytesToSend); + } + else if(_delegate != null) + { + _delegate.getNextBytes(processor); + } + + } + + public void outputClosed() + { + synchronized (_outputLock) + { + _outputOpen = false; + _outputLock.notifyAll(); + } + } + + public boolean isOpenForOutput() + { + return _outputOpen; + } + + public void setOutputStateChangeListener(final StateChangeListener listener) + { + //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java new file mode 100644 index 0000000000..bd9244c858 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java @@ -0,0 +1,438 @@ +/* + * + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transaction.TransactionalState; +import org.apache.qpid.amqp_1_0.type.transport.*; + + +import java.util.*; + +public class ReceivingLinkEndpoint extends LinkEndpoint +{ + + + private static class TransientState + { + + UnsignedInteger _deliveryId; + int _credit = 1; + boolean _settled; + + private TransientState(final UnsignedInteger transferId) + { + _deliveryId = transferId; + } + + void incrementCredit() + { + _credit++; + } + + public int getCredit() + { + return _credit; + } + + public UnsignedInteger getDeliveryId() + { + return _deliveryId; + } + + public boolean isSettled() + { + return _settled; + } + + public void setSettled(boolean settled) + { + _settled = settled; + } + } + + private Map _unsettledMap = new LinkedHashMap(); + private Map _unsettledIds = new LinkedHashMap(); + private boolean _creditWindow; + private boolean _remoteDrain; + private UnsignedInteger _remoteTransferCount; + private UnsignedInteger _drainLimit; + + + public ReceivingLinkEndpoint(final SessionEndpoint session, String name) + { + this(session,name,null); + } + + public ReceivingLinkEndpoint(final SessionEndpoint session, String name, Map unsettledMap) + { + super(session, name, unsettledMap); + setDeliveryCount(UnsignedInteger.valueOf(0)); + setLinkEventListener(ReceivingLinkListener.DEFAULT); + } + + public ReceivingLinkEndpoint(final SessionEndpoint session, final Attach attach) + { + super(session, attach); + setDeliveryCount(attach.getInitialDeliveryCount()); + setLinkEventListener(ReceivingLinkListener.DEFAULT); + setSendingSettlementMode(attach.getSndSettleMode()); + setReceivingSettlementMode(attach.getRcvSettleMode()); + } + + + @Override public Role getRole() + { + return Role.RECEIVER; + } + + @Override + public void receiveTransfer(final Transfer transfer, final Delivery delivery) + { + synchronized (getLock()) + { + TransientState transientState; + boolean existingState = _unsettledMap.containsKey(transfer.getDeliveryTag()); + _unsettledMap.put(transfer.getDeliveryTag(), transfer.getState()); + if(!existingState) + { + transientState = new TransientState(transfer.getDeliveryId()); + if(Boolean.TRUE.equals(transfer.getSettled())) + { + transientState.setSettled(true); + } + _unsettledIds.put(transfer.getDeliveryTag(), transientState); + setLinkCredit(getLinkCredit().subtract(UnsignedInteger.ONE)); + setDeliveryCount(getDeliveryCount().add(UnsignedInteger.ONE)); + + } + else + { + transientState = _unsettledIds.get(transfer.getDeliveryTag()); + transientState.incrementCredit(); + if(Boolean.TRUE.equals(transfer.getSettled())) + { + transientState.setSettled(true); + } + } + + if(transientState.isSettled()) + { + _unsettledMap.remove(transfer.getDeliveryTag()); + } + getLinkEventListener().messageTransfer(transfer); + + + getLock().notifyAll(); + } + } + + @Override public void receiveFlow(final Flow flow) + { + synchronized (getLock()) + { + super.receiveFlow(flow); + _remoteDrain = Boolean.TRUE.equals((Boolean)flow.getDrain()); + setAvailable(flow.getAvailable()); + _remoteTransferCount = flow.getDeliveryCount(); + getLock().notifyAll(); + } + } + + + public boolean isDrained() + { + return getDrain() && getDeliveryCount().equals(getDrainLimit()); + } + + @Override + public void settledByPeer(final Binary deliveryTag) + { + synchronized (getLock()) + { + // TODO XXX : need to do anything about the window here? + if(settled(deliveryTag) && _creditWindow) + { + sendFlowConditional(); + } + } + } + + public boolean settled(final Binary deliveryTag) + { + synchronized(getLock()) + { + boolean deleted; + if(deleted = (_unsettledIds.remove(deliveryTag) != null)) + { + _unsettledMap.remove(deliveryTag); + + getLock().notifyAll(); + } + + return deleted; + } + } + + public void updateDisposition(final Binary deliveryTag, DeliveryState state, boolean settled) + { + synchronized(getLock()) + { + if(_unsettledMap.containsKey(deliveryTag)) + { + boolean outcomeUpdate = false; + Outcome outcome=null; + if(state instanceof Outcome) + { + outcome = (Outcome)state; + } + else if(state instanceof TransactionalState) + { + // TODO? Is this correct + outcome = ((TransactionalState)state).getOutcome(); + } + + if(outcome != null) + { + Object oldOutcome = _unsettledMap.put(deliveryTag, outcome); + outcomeUpdate = !outcome.equals(oldOutcome); + } + + + + + TransientState transientState = _unsettledIds.get(deliveryTag); + if(outcomeUpdate || settled) + { + + final UnsignedInteger transferId = transientState.getDeliveryId(); + + getSession().updateDisposition(getRole(), transferId, transferId, state, settled); + } + + + if(settled) + { + + if(settled(deliveryTag)) + { + if(!isDetached() && _creditWindow) + { + setLinkCredit(getLinkCredit().add(UnsignedInteger.ONE)); + sendFlowConditional(); + } + else + { + getSession().sendFlowConditional(); + } + } + } + getLock().notifyAll(); + } + else + { + TransientState transientState = _unsettledIds.get(deliveryTag); + if(_creditWindow) + { + setLinkCredit(getLinkCredit().add(UnsignedInteger.ONE)); + sendFlowConditional(); + } + + } + } + + } + + + public void setCreditWindow() + { + setCreditWindow(true); + } + public void setCreditWindow(boolean window) + { + + _creditWindow = window; + sendFlowConditional(); + + } + + public void drain() + { + synchronized (getLock()) + { + setDrain(true); + _creditWindow = false; + _drainLimit = getDeliveryCount().add(getLinkCredit()); + sendFlow(); + getLock().notifyAll(); + } + } + + @Override + public void receiveDeliveryState(final Delivery unsettled, final DeliveryState state, final Boolean settled) + { + super.receiveDeliveryState(unsettled, state, settled); + if(_creditWindow) + { + if(Boolean.TRUE.equals(settled)) + { + setLinkCredit(getLinkCredit().add(UnsignedInteger.ONE)); + sendFlowConditional(); + } + } + } + + public void requestTransactionalSend(Object txnId) + { + synchronized (getLock()) + { + setDrain(true); + _creditWindow = false; + setTransactionId(txnId); + sendFlow(); + getLock().notifyAll(); + } + } + + private void sendFlow(final Object transactionId) + { + sendFlow(); + } + + + public void clearDrain() + { + synchronized (getLock()) + { + setDrain(false); + sendFlow(); + getLock().notifyAll(); + } + } + + public void updateAllDisposition(Binary deliveryTag, DeliveryState deliveryState, boolean settled) + { + synchronized(getLock()) + { + if(!_unsettledIds.isEmpty()) + { + Binary firstTag = _unsettledIds.keySet().iterator().next(); + Binary lastTag = deliveryTag; + updateDispositions(firstTag, lastTag, deliveryState, settled); + } + } + } + + private void updateDispositions(Binary firstTag, Binary lastTag, DeliveryState state, boolean settled) + { + SortedMap ranges = new TreeMap(); + + synchronized(getLock()) + { + + Iterator iter = _unsettledIds.keySet().iterator(); + List tagsToUpdate = new ArrayList(); + Binary tag = null; + + while(iter.hasNext() && !(tag = iter.next()).equals(firstTag)); + + if(firstTag.equals(tag)) + { + tagsToUpdate.add(tag); + + UnsignedInteger deliveryId = _unsettledIds.get(firstTag).getDeliveryId(); + + UnsignedInteger first = deliveryId; + UnsignedInteger last = first; + + while(iter.hasNext()) + { + tag = iter.next(); + tagsToUpdate.add(tag); + + deliveryId = _unsettledIds.get(firstTag).getDeliveryId(); + + if(deliveryId.equals(last.add(UnsignedInteger.ONE))) + { + last = deliveryId; + } + else + { + ranges.put(first,last); + first = last = deliveryId; + } + + if(tag.equals(lastTag)) + { + break; + } + } + + ranges.put(first,last); + } + + if(settled) + { + + for(Binary deliveryTag : tagsToUpdate) + { + if(settled(deliveryTag) && _creditWindow) + { + setLinkCredit(getLinkCredit().add(UnsignedInteger.valueOf(1))); + } + } + sendFlowConditional(); + } + + + + for(Map.Entry range : ranges.entrySet()) + { + getSession().updateDisposition(getRole(), range.getKey(), range.getValue(), state, settled); + } + + + getLock().notifyAll(); + } + + } + + @Override + public void settle(Binary deliveryTag) + { + super.settle(deliveryTag); + if(_creditWindow) + { + sendFlowConditional(); + } + + } + + public void flowStateChanged() + { + } + + public UnsignedInteger getDrainLimit() + { + return _drainLimit; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkListener.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkListener.java new file mode 100644 index 0000000000..c0464fbff6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkListener.java @@ -0,0 +1,43 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.transport.*; + +public interface ReceivingLinkListener extends LinkEventListener +{ + void messageTransfer(Transfer xfr); + + class DefaultLinkEventListener implements org.apache.qpid.amqp_1_0.transport.ReceivingLinkListener + { + public void messageTransfer(final Transfer xfr) + { + + } + + public void remoteDetached(final LinkEndpoint endpoint, final Detach detach) + { + endpoint.detach(); + } + } + + public static final org.apache.qpid.amqp_1_0.transport.ReceivingLinkListener DEFAULT = new DefaultLinkEventListener(); + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingSessionHalfEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingSessionHalfEndpoint.java new file mode 100644 index 0000000000..d4b8e500d9 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingSessionHalfEndpoint.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.transport; + +public class ReceivingSessionHalfEndpoint extends SessionHalfEndpoint +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpoint.java new file mode 100644 index 0000000000..21c33d848d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpoint.java @@ -0,0 +1,39 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.security.SaslChallenge; +import org.apache.qpid.amqp_1_0.type.security.SaslInit; +import org.apache.qpid.amqp_1_0.type.security.SaslMechanisms; +import org.apache.qpid.amqp_1_0.type.security.SaslOutcome; +import org.apache.qpid.amqp_1_0.type.security.SaslResponse; + +public interface SASLEndpoint +{ + void receiveSaslInit(SaslInit saslInit); + + void receiveSaslMechanisms(SaslMechanisms saslMechanisms); + + void receiveSaslChallenge(SaslChallenge saslChallenge); + + void receiveSaslResponse(SaslResponse saslResponse); + + void receiveSaslOutcome(SaslOutcome saslOutcome); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpointImpl.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpointImpl.java new file mode 100644 index 0000000000..b371b1217c --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpointImpl.java @@ -0,0 +1,291 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.SaslFrameBody; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; +import org.apache.qpid.amqp_1_0.type.security.SaslChallenge; +import org.apache.qpid.amqp_1_0.type.security.SaslInit; +import org.apache.qpid.amqp_1_0.type.security.SaslMechanisms; +import org.apache.qpid.amqp_1_0.type.security.SaslOutcome; +import org.apache.qpid.amqp_1_0.type.security.SaslResponse; + + +import javax.security.auth.callback.CallbackHandler; +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslClient; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; +import java.io.PrintWriter; +import java.util.Arrays; + + +public class SASLEndpointImpl + implements DescribedTypeConstructorRegistry.Source, ValueWriter.Registry.Source, SASLEndpoint +{ + private static final short SASL_CONTROL_CHANNEL = (short) 0; + + private static final byte[] EMPTY_CHALLENGE = new byte[0]; + + private FrameTransport _transport; + + + private static enum State + { + BEGIN_SERVER, + BEGIN_CLIENT, + SENT_MECHANISMS, + SENT_INIT, + SENT_REPSONSE, + SENT_CHALLENGE, + SENT_OUTCOME + }; + + + public PrintWriter _out; + + + private State _state; + + private SaslClient _saslClient; + private SaslServer _saslServer; + + private boolean _isReadable; + private boolean _isWritable; + private boolean _closedForInput; + private boolean _closedForOutput; + + private AMQPDescribedTypeRegistry _describedTypeRegistry = AMQPDescribedTypeRegistry.newInstance().registerSecurityLayer(); + + private FrameOutputHandler _frameOutputHandler; + + private byte _majorVersion; + private byte _minorVersion; + private byte _revision; + private UnsignedInteger _handleMax = UnsignedInteger.MAX_VALUE; + private ConnectionEventListener _connectionEventListener = ConnectionEventListener.DEFAULT; + private Symbol[] _mechanisms; + private Symbol _mechanism; + + + private SASLEndpointImpl(FrameTransport transport, State initialState, Symbol... mechanisms) + { + _transport = transport; + _state = initialState; + _mechanisms = mechanisms; + } + + + public void setFrameOutputHandler(final FrameOutputHandler frameOutputHandler) + { + _frameOutputHandler = frameOutputHandler; + if(_state == State.BEGIN_SERVER) + { + sendMechanisms(); + } + } + + private synchronized void sendMechanisms() + { + SaslMechanisms saslMechanisms = new SaslMechanisms(); + + saslMechanisms.setSaslServerMechanisms(_mechanisms); + + _state = State.SENT_MECHANISMS; + + send(saslMechanisms); + } + + public boolean isReadable() + { + return _isReadable; + } + + public boolean isWritable() + { + return _isWritable; + } + + + public synchronized void send(SaslFrameBody body) + { + if(!_closedForOutput) + { + if(_out != null) + { + _out.println("SEND : " + body); + _out.flush(); + } + //_frameOutputHandler.send(new SASLFrame(body)); + } + } + + + + public void invalidHeaderReceived() + { + // TODO + _closedForInput = true; + } + + public synchronized boolean closedForInput() + { + return _closedForInput; + } + + public synchronized void protocolHeaderReceived(final byte major, final byte minorVersion, final byte revision) + { + _majorVersion = major; + _minorVersion = minorVersion; + _revision = revision; + } + + + public synchronized void receive(final short channel, final Object frame) + { + if(_out != null) + { + _out.println( "RECV["+channel+"] : " + frame); + _out.flush(); + } + if(frame instanceof SaslFrameBody) + { + ((SaslFrameBody)frame).invoke(this); + } + else + { + // TODO + } + } + + public AMQPDescribedTypeRegistry getDescribedTypeRegistry() + { + return _describedTypeRegistry; + } + + public synchronized void setClosedForOutput(boolean b) + { + _closedForOutput = true; + notifyAll(); + } + + public synchronized boolean closedForOutput() + { + return _closedForOutput; + } + + + public Object getLock() + { + return this; + } + + + public byte getMajorVersion() + { + return _majorVersion; + } + + + public byte getMinorVersion() + { + return _minorVersion; + } + + public byte getRevision() + { + return _revision; + } + + + public void receiveSaslInit(final SaslInit saslInit) + { + _mechanism = saslInit.getMechanism(); + try + { + _saslServer = Sasl.createSaslServer(_mechanism.toString(), "AMQP", "localhost", null, createServerCallbackHandler(_mechanism)); + } + catch (SaslException e) + { + e.printStackTrace(); //TODO + } + } + + private CallbackHandler createServerCallbackHandler(final Symbol mechanism) + { + return null; //TODO + } + + public synchronized void receiveSaslMechanisms(final SaslMechanisms saslMechanisms) + { + Symbol[] serverMechanisms = saslMechanisms.getSaslServerMechanisms(); + for(Symbol mechanism : _mechanisms) + { + if(Arrays.asList(serverMechanisms).contains(mechanism)) + { + _mechanism = mechanism; + break; + } + } + // TODO - no matching mechanism + try + { + _saslClient = Sasl.createSaslClient(new String[] { _mechanism.toString() }, null, "AMQP", "localhost", null, + createClientCallbackHandler(_mechanism)); + SaslInit init = new SaslInit(); + init.setMechanism(_mechanism); + init.setInitialResponse(_saslClient.hasInitialResponse() ? new Binary(_saslClient.evaluateChallenge(EMPTY_CHALLENGE)) : null); + send(init); + } + catch (SaslException e) + { + e.printStackTrace(); //TODO + } + } + + private CallbackHandler createClientCallbackHandler(final Symbol mechanism) + { + return null; //TODO + } + + public void receiveSaslChallenge(final SaslChallenge saslChallenge) + { + //TODO + } + + public void receiveSaslResponse(final SaslResponse saslResponse) + { + //TODO + } + + + public void receiveSaslOutcome(final SaslOutcome saslOutcome) + { + //TODO + } + + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLFrameTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLFrameTransport.java new file mode 100644 index 0000000000..8299cddfbe --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLFrameTransport.java @@ -0,0 +1,78 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.framing.SASLFrame; + +public class SASLFrameTransport implements FrameTransport +{ + private final Object _inputLock = new Object(); + private final Object _outputLock = new Object(); + + private volatile boolean _inputOpen; + private volatile boolean _outputOpen; + + public boolean isOpenForInput() + { + return _inputOpen; + } + + public void closeForInput() + { + synchronized(_inputLock) + { + _inputOpen = false; + _inputLock.notifyAll(); + } + } + public void processIncomingFrame(final SASLFrame frame) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public SASLFrame getNextFrame() + { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + public void closeForOutput() + { + synchronized (_outputLock) + { + _outputOpen = false; + _outputLock.notifyAll(); + } + } + + public boolean isOpenForOutput() + { + return _outputOpen; + } + + public void setInputStateChangeListener(final StateChangeListener listener) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void setOutputStateChangeListener(final StateChangeListener listener) + { + //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLTransport.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLTransport.java new file mode 100644 index 0000000000..e140e3acd7 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLTransport.java @@ -0,0 +1,85 @@ +/* + * 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.amqp_1_0.transport; + + +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; + +import java.nio.ByteBuffer; + +public class SASLTransport implements BytesTransport +{ + private final Object _inputLock = new Object(); + private final Object _outputLock = new Object(); + + private volatile boolean _inputOpen; + private volatile boolean _outputOpen; + + private AMQPDescribedTypeRegistry _describedTypeRegistry = AMQPDescribedTypeRegistry.newInstance() + .registerSecurityLayer(); + + public boolean isOpenForInput() + { + return _inputOpen; + } + + public void inputClosed() + { + synchronized(_inputLock) + { + _inputOpen = false; + _inputLock.notifyAll(); + } + } + + public void processBytes(final ByteBuffer buf) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void setInputStateChangeListener(final StateChangeListener listener) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void getNextBytes(final BytesProcessor processor) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void outputClosed() + { + synchronized (_outputLock) + { + _outputOpen = false; + _outputLock.notifyAll(); + } + } + + public boolean isOpenForOutput() + { + return _outputOpen; + } + + public void setOutputStateChangeListener(final StateChangeListener listener) + { + //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkEndpoint.java new file mode 100644 index 0000000000..a53b3661be --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkEndpoint.java @@ -0,0 +1,214 @@ +/* + * + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.transport.Attach; +import org.apache.qpid.amqp_1_0.type.transport.Flow; +import org.apache.qpid.amqp_1_0.type.transport.Role; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + +import java.util.HashMap; +import java.util.Map; + +public class SendingLinkEndpoint extends LinkEndpoint +{ + + private UnsignedInteger _lastDeliveryId; + private Binary _lastDeliveryTag; + private Map _unsettledMap = new HashMap(); + private Binary _transactionId; + + public SendingLinkEndpoint(final SessionEndpoint sessionEndpoint, String name) + { + this(sessionEndpoint, name, null); + } + + public SendingLinkEndpoint(final SessionEndpoint sessionEndpoint, String name, Map unsettled) + { + super(sessionEndpoint, name, unsettled); + init(); + } + + public SendingLinkEndpoint(final SessionEndpoint sessionEndpoint, final Attach attach) + { + super(sessionEndpoint, attach); + setSendingSettlementMode(attach.getSndSettleMode()); + setReceivingSettlementMode(attach.getRcvSettleMode()); + init(); + } + + private void init() + { + setDeliveryCount(UnsignedInteger.valueOf(0)); + setAvailable(UnsignedInteger.valueOf(0)); + setLinkEventListener(SendingLinkListener.DEFAULT); + } + + @Override public Role getRole() + { + return Role.SENDER; + } + + public boolean transfer(final Transfer xfr) + { + SessionEndpoint s = getSession(); + int transferCount; + transferCount = _lastDeliveryTag == null ? 1 : 1; + xfr.setMessageFormat(UnsignedInteger.ZERO); + synchronized(getLock()) + { + + final int currentCredit = getLinkCredit().intValue() - transferCount; + + if(currentCredit < 0) + { + return false; + } + else + { + setLinkCredit(UnsignedInteger.valueOf((int)currentCredit)); + } + + setDeliveryCount(UnsignedInteger.valueOf((getDeliveryCount().intValue() + transferCount))); + + xfr.setHandle(getLocalHandle()); + + s.sendTransfer(xfr, this, !xfr.getDeliveryTag().equals(_lastDeliveryTag)); + + if(!Boolean.TRUE.equals(xfr.getSettled())) + { + _unsettledMap.put(xfr.getDeliveryTag(), xfr.getDeliveryId()); + } + } + + if(Boolean.TRUE.equals(xfr.getMore())) + { + _lastDeliveryTag = xfr.getDeliveryTag(); + } + else + { + _lastDeliveryTag = null; + } + + return true; + } + + + public void drained() + { + synchronized (getLock()) + { + setDeliveryCount(getDeliveryCount().add(getLinkCredit())); + setLinkCredit(UnsignedInteger.ZERO); + sendFlow(); + } + } + + @Override + public void receiveFlow(final Flow flow) + { + super.receiveFlow(flow); + UnsignedInteger t = flow.getDeliveryCount(); + UnsignedInteger c = flow.getLinkCredit(); + setDrain(flow.getDrain()); + + Map options; + if((options = flow.getProperties()) != null) + { + _transactionId = (Binary) options.get(Symbol.valueOf("txn-id")); + } + + if(t == null) + { + setLinkCredit(c); + } + else + { + UnsignedInteger limit = t.add(c); + if(limit.compareTo(getDeliveryCount())<=0) + { + setLinkCredit(UnsignedInteger.valueOf(0)); + } + else + { + setLinkCredit(limit.subtract(getDeliveryCount())); + } + } + getLinkEventListener().flowStateChanged(); + + } + + @Override + public void flowStateChanged() + { + getLinkEventListener().flowStateChanged(); + } + + public boolean hasCreditToSend() + { + UnsignedInteger linkCredit = getLinkCredit(); + return linkCredit != null && (linkCredit.compareTo(UnsignedInteger.valueOf(0)) > 0) + && getSession().hasCreditToSend(); + } + + public void receiveDeliveryState(final Delivery unsettled, + final DeliveryState state, + final Boolean settled) + { + super.receiveDeliveryState(unsettled, state, settled); + if(settled) + { + _unsettledMap.remove(unsettled.getDeliveryTag()); + } + } + + public UnsignedInteger getLastDeliveryId() + { + return _lastDeliveryId; + } + + public void setLastDeliveryId(final UnsignedInteger deliveryId) + { + _lastDeliveryId = deliveryId; + } + + public void updateDisposition(final Binary deliveryTag, DeliveryState state, boolean settled) + { + synchronized(getLock()) + { + UnsignedInteger deliveryId; + if(settled && (deliveryId = _unsettledMap.remove(deliveryTag))!=null) + { + settle(deliveryTag); + getSession().updateDisposition(getRole(), deliveryId, deliveryId, state, settled); + } + + } + } + + public Binary getTransactionId() + { + return _transactionId; + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkListener.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkListener.java new file mode 100644 index 0000000000..09a99f1ba1 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkListener.java @@ -0,0 +1,43 @@ +/* + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.transport.*; + +public interface SendingLinkListener extends LinkEventListener +{ + void flowStateChanged(); + + class DefaultLinkEventListener implements org.apache.qpid.amqp_1_0.transport.SendingLinkListener + { + + public void remoteDetached(final LinkEndpoint endpoint, final org.apache.qpid.amqp_1_0.type.transport.Detach detach) + { + endpoint.detach(); + } + + public void flowStateChanged() + { + + } + } + + public static final org.apache.qpid.amqp_1_0.transport.SendingLinkListener DEFAULT = new DefaultLinkEventListener(); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingSessionHalfEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingSessionHalfEndpoint.java new file mode 100644 index 0000000000..2bc9a42dc5 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingSessionHalfEndpoint.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.transport; + +public class SendingSessionHalfEndpoint extends SessionHalfEndpoint +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SequenceNumber.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SequenceNumber.java new file mode 100644 index 0000000000..3f6490c2aa --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SequenceNumber.java @@ -0,0 +1,110 @@ +/* + * + * 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.amqp_1_0.transport; + +public class SequenceNumber implements Comparable, Cloneable +{ + private int _seqNo; + + public SequenceNumber(int seqNo) + { + _seqNo = seqNo; + } + + public SequenceNumber incr() + { + _seqNo++; + return this; + } + + public SequenceNumber decr() + { + _seqNo--; + return this; + } + + public static SequenceNumber add(SequenceNumber a, int i) + { + return a.clone().add(i); + } + + public static SequenceNumber subtract(SequenceNumber a, int i) + { + return a.clone().add(-i); + } + + private SequenceNumber add(int i) + { + _seqNo+=i; + return this; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + SequenceNumber that = (SequenceNumber) o; + + if (_seqNo != that._seqNo) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + return _seqNo; + } + + public int compareTo(SequenceNumber o) + { + return _seqNo - o._seqNo; + } + + @Override + public SequenceNumber clone() + { + return new SequenceNumber(_seqNo); + } + + @Override + public String toString() + { + return "SN{" + _seqNo + '}'; + } + + public int intValue() + { + return _seqNo; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionAttachment.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionAttachment.java new file mode 100644 index 0000000000..6bb1e922e5 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionAttachment.java @@ -0,0 +1,92 @@ +/* + * + * 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.amqp_1_0.transport; + +public class SessionAttachment +{ + private final SessionEndpoint _sessionEndpoint; + private final ConnectionEndpoint _connectionEndpoint; + private final short _channel; + + public SessionAttachment(SessionEndpoint sessionEndpoint, ConnectionEndpoint connectionEndpoint, short channel) + { + _sessionEndpoint = sessionEndpoint; + _connectionEndpoint = connectionEndpoint; + _channel = channel; + } + + public SessionEndpoint getSessionEndpoint() + { + return _sessionEndpoint; + } + + public ConnectionEndpoint getConnectionEndpoint() + { + return _connectionEndpoint; + } + + public short getChannel() + { + return _channel; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + SessionAttachment that = (SessionAttachment) o; + + if (_channel != that._channel) + { + return false; + } + if (_connectionEndpoint != null + ? !_connectionEndpoint.equals(that._connectionEndpoint) + : that._connectionEndpoint != null) + { + return false; + } + if (_sessionEndpoint != null ? !_sessionEndpoint.equals(that._sessionEndpoint) : that._sessionEndpoint != null) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + int result = _sessionEndpoint != null ? _sessionEndpoint.hashCode() : 0; + result = 31 * result + (_connectionEndpoint != null ? _connectionEndpoint.hashCode() : 0); + result = 31 * result + (int) _channel; + return result; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java new file mode 100644 index 0000000000..4b8bf82a4a --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java @@ -0,0 +1,781 @@ +/* + * + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.framing.OversizeFrameException; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.Source; +import org.apache.qpid.amqp_1_0.type.messaging.Target; +import org.apache.qpid.amqp_1_0.type.messaging.TerminusDurability; +import org.apache.qpid.amqp_1_0.type.messaging.TerminusExpiryPolicy; +import org.apache.qpid.amqp_1_0.type.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.TxnCapability; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; + + +import java.nio.ByteBuffer; +import java.util.*; + +public class SessionEndpoint +{ + private SessionState _state = SessionState.INACTIVE; + + private final Map _linkMap = new HashMap(); + private final Map _localLinkEndpoints = new HashMap(); + private final Map _remoteLinkEndpoints = new HashMap(); + + private long _timeout; + + + private ConnectionEndpoint _connection; + private long _lastAttachedTime; + + private short _receivingChannel; + private short _sendingChannel; + + private LinkedHashMap _outgoingUnsettled; + private LinkedHashMap _incomingUnsettled; + + // has to be a power of two + private static final int DEFAULT_SESSION_BUFFER_SIZE = 1 << 11; + private static final int BUFFER_SIZE_MASK = DEFAULT_SESSION_BUFFER_SIZE - 1; + + private SequenceNumber _nextIncomingTransferId; + private SequenceNumber _nextOutgoingTransferId; + + private int _nextOutgoingDeliveryId; + + //private SequenceNumber _incomingLWM; + //private SequenceNumber _outgoingLWM; + + private UnsignedInteger _outgoingSessionCredit; + + + + private UnsignedInteger _initialOutgoingId; + + private SessionEventListener _sessionEventListener = SessionEventListener.DEFAULT; + + private int _availableIncomingCredit; + private int _availableOutgoingCredit; + private UnsignedInteger _lastSentIncomingLimit; + + public SessionEndpoint(final ConnectionEndpoint connectionEndpoint) + { + this(connectionEndpoint, UnsignedInteger.valueOf(0)); + } + + public SessionEndpoint(final ConnectionEndpoint connectionEndpoint, Begin begin) + { + this(connectionEndpoint, UnsignedInteger.valueOf(0)); + _state = SessionState.BEGIN_RECVD; + _nextIncomingTransferId = new SequenceNumber(begin.getNextOutgoingId().intValue()); + } + + + public SessionEndpoint(final ConnectionEndpoint connectionEndpoint, UnsignedInteger nextOutgoingId) + { + _connection = connectionEndpoint; + + _initialOutgoingId = nextOutgoingId; + _nextOutgoingTransferId = new SequenceNumber(nextOutgoingId.intValue()); + + _outgoingUnsettled = new LinkedHashMap(DEFAULT_SESSION_BUFFER_SIZE); + _incomingUnsettled = new LinkedHashMap(DEFAULT_SESSION_BUFFER_SIZE); + _availableIncomingCredit = DEFAULT_SESSION_BUFFER_SIZE; + _availableOutgoingCredit = DEFAULT_SESSION_BUFFER_SIZE; + } + + + public void setReceivingChannel(final short receivingChannel) + { + _receivingChannel = receivingChannel; + switch(_state) + { + case INACTIVE: + _state = SessionState.BEGIN_RECVD; + break; + case BEGIN_SENT: + _state = SessionState.ACTIVE; + break; + default: + // TODO error + + } + } + + + public void setSendingChannel(final short sendingChannel) + { + _sendingChannel = sendingChannel; + switch(_state) + { + case INACTIVE: + _state = SessionState.BEGIN_SENT; + break; + case BEGIN_RECVD: + _state = SessionState.ACTIVE; + break; + default: + // TODO error + + } + } + + public SessionState getState() + { + return _state; + } + + public void end() + { + end(null); + } + + public void end(final End end) + { + synchronized(getLock()) + { + switch(_state) + { + case END_SENT: + _state = SessionState.ENDED; + break; + case ACTIVE: + detachLinks(); + _sessionEventListener.remoteEnd(end); + short sendChannel = getSendingChannel(); + _connection.sendEnd(sendChannel, new End()); + _state = end == null ? SessionState.END_SENT : SessionState.ENDED; + break; + default: + sendChannel = getSendingChannel(); + End reply = new End(); + Error error = new Error(); + error.setCondition(AmqpError.ILLEGAL_STATE); + error.setDescription("END called on Session which has not been opened"); + reply.setError(error); + _connection.sendEnd(sendChannel, reply); + break; + + + } + getLock().notifyAll(); + } + } + + private void detachLinks() + { + Collection handles = new ArrayList(_remoteLinkEndpoints.keySet()); + for(UnsignedInteger handle : handles) + { + detach(handle, null); + } + } + + public short getSendingChannel() + { + return _sendingChannel; + } + + + public void receiveAttach(final Attach attach) + { + if(_state == SessionState.ACTIVE) + { + UnsignedInteger handle = attach.getHandle(); + if(_remoteLinkEndpoints.containsKey(handle)) + { + // TODO - Error - handle busy? + } + else + { + LinkEndpoint endpoint = getLinkMap().get(attach.getName()); + if(endpoint == null) + { + endpoint = attach.getRole() == Role.RECEIVER + ? new SendingLinkEndpoint(this, attach) + : new ReceivingLinkEndpoint(this, attach); + + // TODO : fix below - distinguish between local and remote owned + endpoint.setSource(attach.getSource()); + endpoint.setTarget(attach.getTarget()); + + + } + + if(attach.getRole() == Role.SENDER) + { + endpoint.setDeliveryCount(attach.getInitialDeliveryCount()); + } + + _remoteLinkEndpoints.put(handle, endpoint); + + if(!_localLinkEndpoints.containsKey(endpoint)) + { + UnsignedInteger localHandle = findNextAvailableHandle(); + endpoint.setLocalHandle(localHandle); + _localLinkEndpoints.put(endpoint, localHandle); + + _sessionEventListener.remoteLinkCreation(endpoint); + + + } + else + { + endpoint.receiveAttach(attach); + } + } + } + } + + private void send(final FrameBody frameBody) + { + _connection.send(this.getSendingChannel(), frameBody); + } + + + private int send(final FrameBody frameBody, ByteBuffer payload) + { + return _connection.send(this.getSendingChannel(), frameBody, payload); + } + + private UnsignedInteger findNextAvailableHandle() + { + int i = 0; + do + { + if(!_localLinkEndpoints.containsValue(UnsignedInteger.valueOf(i))) + { + return UnsignedInteger.valueOf(i); + } + } while(++i != 0); + + // TODO + throw new RuntimeException(); + } + + public void receiveDetach(final Detach detach) + { + UnsignedInteger handle = detach.getHandle(); + detach(handle, detach); + } + + private void detach(UnsignedInteger handle, Detach detach) + { + if(_remoteLinkEndpoints.containsKey(handle)) + { + LinkEndpoint endpoint = _remoteLinkEndpoints.remove(handle); + + endpoint.remoteDetached(detach); + + _localLinkEndpoints.remove(endpoint); + + + } + else + { + // TODO + } + } + + public void receiveTransfer(final Transfer transfer) + { + synchronized(getLock()) + { + _nextIncomingTransferId.incr(); +/* + _availableIncomingCredit--; +*/ + + UnsignedInteger handle = transfer.getHandle(); + + + + LinkEndpoint endpoint = _remoteLinkEndpoints.get(handle); + + if(endpoint == null) + { + //TODO - error unknown link + System.err.println("Unknown endpoint " + transfer); + + } + + Delivery delivery = _incomingUnsettled.get(transfer.getDeliveryId()); + if(delivery == null) + { + delivery = new Delivery(transfer, endpoint); + _incomingUnsettled.put(transfer.getDeliveryId(),delivery); + if(delivery.isSettled() || Boolean.TRUE.equals(transfer.getAborted())) + { +/* + _availableIncomingCredit++; +*/ + } + } + else + { + if(delivery.getDeliveryId().equals(transfer.getDeliveryId())) + { + delivery.addTransfer(transfer); + if(delivery.isSettled()) + { +/* + _availableIncomingCredit++; +*/ + } + else if(Boolean.TRUE.equals(transfer.getAborted())) + { +/* + _availableIncomingCredit += delivery.getTransfers().size(); +*/ + } + } + else + { + // TODO - error + System.err.println("Incorrect transfer id " + transfer); + } + } + + if(endpoint != null) + { + endpoint.receiveTransfer(transfer, delivery); + } + + if((delivery.isComplete() && delivery.isSettled() || Boolean.TRUE.equals(transfer.getAborted()))) + { + _incomingUnsettled.remove(transfer.getDeliveryId()); + } + } + } + + public void receiveFlow(final Flow flow) + { + + synchronized(getLock()) + { + UnsignedInteger handle = flow.getHandle(); + LinkEndpoint endpoint = handle == null ? null : _remoteLinkEndpoints.get(handle); + + final UnsignedInteger nextOutgoingId = flow.getNextIncomingId() == null ? _initialOutgoingId : flow.getNextIncomingId(); + int limit = (nextOutgoingId.intValue() + flow.getIncomingWindow().intValue()); + _outgoingSessionCredit = UnsignedInteger.valueOf(limit - _nextOutgoingTransferId.intValue()); + + if(endpoint != null) + { + endpoint.receiveFlow( flow ); + } + else + { + for(LinkEndpoint le : _remoteLinkEndpoints.values()) + { + le.flowStateChanged(); + } + } + + getLock().notifyAll(); + } + + + } + + public void receiveDisposition(final Disposition disposition) + { + Role dispositionRole = disposition.getRole(); + + LinkedHashMap unsettledTransfers; + + if(dispositionRole == Role.RECEIVER) + { + unsettledTransfers = _outgoingUnsettled; + } + else + { + unsettledTransfers = _incomingUnsettled; + + } + + UnsignedInteger deliveryId = disposition.getFirst(); + UnsignedInteger last = disposition.getLast(); + if(last == null) + { + last = deliveryId; + } + + + while(deliveryId.compareTo(last)<=0) + { + + Delivery delivery = unsettledTransfers.get(deliveryId); + if(delivery != null) + { + delivery.getLinkEndpoint().receiveDeliveryState(delivery, + disposition.getState(), + disposition.getSettled()); + } + deliveryId = deliveryId.add(UnsignedInteger.ONE); + } + if(disposition.getSettled()) + { + checkSendFlow(); + } + + } + + private void checkSendFlow() + { + //TODO + } + + public SendingLinkEndpoint createSendingLinkEndpoint(final String name, final String targetAddr, final String sourceAddr) + { + return createSendingLinkEndpoint(name, targetAddr, sourceAddr, null); + } + + public SendingLinkEndpoint createSendingLinkEndpoint(final String name, final String targetAddr, final String sourceAddr, Map unsettled) + { + return createSendingLinkEndpoint(name, targetAddr, sourceAddr, false, unsettled); + } + + public SendingLinkEndpoint createSendingLinkEndpoint(final String name, final String targetAddr, + final String sourceAddr, boolean durable, + Map unsettled) + { + + Source source = new Source(); + source.setAddress(sourceAddr); + Target target = new Target(); + target.setAddress(targetAddr); + if(durable) + { + target.setDurable(TerminusDurability.UNSETTLED_STATE); + target.setExpiryPolicy(TerminusExpiryPolicy.NEVER); + } + + return createSendingLinkEndpoint(name, source, target, unsettled); + + } + + public SendingLinkEndpoint createSendingLinkEndpoint(final String name, final Source source, final org.apache.qpid.amqp_1_0.type.Target target) + { + return createSendingLinkEndpoint(name, source, target, null); + } + + public SendingLinkEndpoint createSendingLinkEndpoint(final String name, final Source source, final org.apache.qpid.amqp_1_0.type.Target target, Map unsettled) + { + SendingLinkEndpoint endpoint = new SendingLinkEndpoint(this, name, unsettled); + endpoint.setSource(source); + endpoint.setTarget(target); + UnsignedInteger handle = findNextAvailableHandle(); + _localLinkEndpoints.put(endpoint, handle); + endpoint.setLocalHandle(handle); + getLinkMap().put(name, endpoint); + + return endpoint; + } + + public void sendAttach(Attach attach) + { + send(attach); + } + + public void sendTransfer(final Transfer xfr, SendingLinkEndpoint endpoint, boolean newDelivery) + { + _nextOutgoingTransferId.incr(); + UnsignedInteger deliveryId; + if(newDelivery) + { + deliveryId = UnsignedInteger.valueOf(_nextOutgoingDeliveryId++); + endpoint.setLastDeliveryId(deliveryId); + } + else + { + deliveryId = endpoint.getLastDeliveryId(); + } + xfr.setDeliveryId(deliveryId); + + if(!Boolean.TRUE.equals(xfr.getSettled())) + { + Delivery delivery; + if((delivery = _outgoingUnsettled.get(deliveryId))== null) + { + delivery = new Delivery(xfr, endpoint); + _outgoingUnsettled.put(deliveryId, delivery); + + } + else + { + delivery.addTransfer(xfr); + } + _outgoingSessionCredit = _outgoingSessionCredit.subtract(UnsignedInteger.ONE); + endpoint.addUnsettled(delivery); + + } + + try + { + ByteBuffer payload = xfr.getPayload(); + int payloadSent = send(xfr, payload); + + if(payload != null && payloadSent < payload.remaining()) + { + payload = payload.duplicate(); +try +{ + payload.position(payload.position()+payloadSent); +} +catch(IllegalArgumentException e) +{ + System.err.println("UNEXPECTED"); + System.err.println("Payload Position: " + payload.position()); + System.err.println("Payload Sent: " + payloadSent); + System.err.println("Payload Remaining: " + payload.remaining()); + throw e; + +} + + Transfer secondTransfer = new Transfer(); + + secondTransfer.setDeliveryTag(xfr.getDeliveryTag()); + secondTransfer.setHandle(xfr.getHandle()); + secondTransfer.setSettled(xfr.getSettled()); + secondTransfer.setState(xfr.getState()); + secondTransfer.setMessageFormat(xfr.getMessageFormat()); + secondTransfer.setPayload(payload); + + sendTransfer(secondTransfer, endpoint, false); + + } + } + catch(OversizeFrameException e) + { + e.printStackTrace(); + } + + } + + public Object getLock() + { + return _connection.getLock(); + } + + public ReceivingLinkEndpoint createReceivingLinkEndpoint(final String name, + String targetAddr, + String sourceAddr, + UnsignedInteger initialCredit, + final DistributionMode distributionMode) + { + Source source = new Source(); + source.setAddress(sourceAddr); + source.setDistributionMode(distributionMode); + Target target = new Target(); + target.setAddress(targetAddr); + + return createReceivingLinkEndpoint(name, target, source, initialCredit); + } + + public ReceivingLinkEndpoint createReceivingLinkEndpoint(final String name, + Target target, + Source source, + UnsignedInteger initialCredit) + { + ReceivingLinkEndpoint endpoint = new ReceivingLinkEndpoint(this, name); + endpoint.setLinkCredit(initialCredit); + endpoint.setSource(source); + endpoint.setTarget(target); + UnsignedInteger handle = findNextAvailableHandle(); + _localLinkEndpoints.put(endpoint, handle); + endpoint.setLocalHandle(handle); + getLinkMap().put(name, endpoint); + + return endpoint; + + } + + public void updateDisposition(final Role role, + final UnsignedInteger first, + final UnsignedInteger last, + final DeliveryState state, + final boolean settled) + { + + + Disposition disposition = new Disposition(); + disposition.setRole(role); + disposition.setFirst(first); + disposition.setLast(last); + disposition.setSettled(settled); + + disposition.setState(state); + + + if(settled) + { + if(role == Role.RECEIVER) + { + SequenceNumber pos = new SequenceNumber(first.intValue()); + SequenceNumber end = new SequenceNumber(last.intValue()); + while(pos.compareTo(end)<=0) + { + Delivery d = _incomingUnsettled.remove(new UnsignedInteger(pos.intValue())); + +/* + _availableIncomingCredit += d.getTransfers().size(); +*/ + + pos.incr(); + } + } + } + + send(disposition); + checkSendFlow(); + } + + public void settle(Role role, final UnsignedInteger deliveryId) + { + if(role == Role.RECEIVER) + { + Delivery d = _incomingUnsettled.remove(deliveryId); + if(d != null) + { +/* + _availableIncomingCredit += d.getTransfers().size(); +*/ + } + } + else + { + Delivery d = _outgoingUnsettled.remove(deliveryId); +/* if(d != null) + { + _availableOutgoingCredit += d.getTransfers().size(); + + }*/ + } + + } + + public void sendFlow() + { + sendFlow(new Flow()); + } + public void sendFlow(final Flow flow) + { + final int nextIncomingId = _nextIncomingTransferId.intValue(); + flow.setNextIncomingId(UnsignedInteger.valueOf(nextIncomingId)); + flow.setIncomingWindow(UnsignedInteger.valueOf(_availableIncomingCredit)); + _lastSentIncomingLimit = UnsignedInteger.valueOf(nextIncomingId + _availableIncomingCredit); + + flow.setNextOutgoingId(UnsignedInteger.valueOf(_nextOutgoingTransferId.intValue())); + flow.setOutgoingWindow(UnsignedInteger.valueOf(_availableOutgoingCredit)); + send(flow); + } + + public void sendFlowConditional() + { + UnsignedInteger clientsCredit = _lastSentIncomingLimit.subtract(UnsignedInteger.valueOf(_nextIncomingTransferId.intValue())); + int i = UnsignedInteger.valueOf(_availableIncomingCredit).subtract(clientsCredit).compareTo(clientsCredit); + if(i >=0) + { + sendFlow(); + } + + } + + public void sendDetach(Detach detach) + { + send(detach); + + } + + void doEnd(End end) + { + } + + public void setNextIncomingId(final UnsignedInteger nextIncomingId) + { + _nextIncomingTransferId = new SequenceNumber(nextIncomingId.intValue()); + + } + + public void setOutgoingSessionCredit(final UnsignedInteger outgoingSessionCredit) + { + _outgoingSessionCredit = outgoingSessionCredit; + } + + public UnsignedInteger getNextOutgoingId() + { + return UnsignedInteger.valueOf(_nextOutgoingTransferId.intValue()); + } + + public UnsignedInteger getOutgoingWindowSize() + { + return UnsignedInteger.valueOf(_availableOutgoingCredit); + } + + public boolean hasCreditToSend() + { + boolean b = _outgoingSessionCredit != null && _outgoingSessionCredit.intValue() > 0; + boolean b1 = getOutgoingWindowSize() != null && getOutgoingWindowSize().compareTo(UnsignedInteger.ZERO) > 0; + return b && b1; + } + + public UnsignedInteger getIncomingWindowSize() + { + return UnsignedInteger.valueOf(_availableIncomingCredit); + } + + public SessionEventListener getSessionEventListener() + { + return _sessionEventListener; + } + + public void setSessionEventListener(final SessionEventListener sessionEventListener) + { + _sessionEventListener = sessionEventListener; + } + + public ConnectionEndpoint getConnection() + { + return _connection; + } + + public SendingLinkEndpoint createTransactionController(String name, TxnCapability... capabilities) + { + Coordinator coordinator = new Coordinator(); + coordinator.setCapabilities(capabilities); + + Source src = new Source(); + + return createSendingLinkEndpoint(name, src, coordinator); + } + + Map getLinkMap() + { + return _linkMap; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEventListener.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEventListener.java new file mode 100644 index 0000000000..81d51b5908 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEventListener.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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.transport.End; + +public interface SessionEventListener +{ + class DefaultSessionEventListener implements SessionEventListener + { + public void remoteLinkCreation(final LinkEndpoint endpoint) + { + endpoint.attach(); + endpoint.detach(); + } + + public void remoteEnd(End end) + { + + } + + } + + public static final SessionEventListener DEFAULT = new DefaultSessionEventListener(); + + void remoteLinkCreation(LinkEndpoint endpoint); + + void remoteEnd(End end); + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionHalfEndpoint.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionHalfEndpoint.java new file mode 100644 index 0000000000..fce1ce021f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionHalfEndpoint.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.transport; + +public class SessionHalfEndpoint +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionState.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionState.java new file mode 100644 index 0000000000..b09e27d980 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionState.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.amqp_1_0.transport; + +public enum SessionState +{ + ACTIVE, + INACTIVE, + BEGIN_SENT, + BEGIN_RECVD, + END_SENT, + END_RECVD, + ENDED; + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/StateChangeListener.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/StateChangeListener.java new file mode 100644 index 0000000000..a02e110d8b --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/StateChangeListener.java @@ -0,0 +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.amqp_1_0.transport; + +public interface StateChangeListener +{ + void onStateChange(boolean active); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/UnsettledTransfer.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/UnsettledTransfer.java new file mode 100644 index 0000000000..7a39fd9a54 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/UnsettledTransfer.java @@ -0,0 +1,53 @@ +/* + * + * 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.amqp_1_0.transport; + +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + +public class UnsettledTransfer +{ + private final Transfer _transfer; + private final LinkEndpoint _linkEndpoint; + + public UnsettledTransfer(final Transfer transfer, final LinkEndpoint linkEndpoint) + { + _transfer = transfer; + _linkEndpoint = linkEndpoint; + } + + public Transfer getTransfer() + { + return _transfer; + } + + public LinkEndpoint getLinkEndpoint() + { + return _linkEndpoint; + } + + @Override public String toString() + { + return "UnsettledTransfer{" + + "_transfer=" + _transfer + + ", _linkEndpoint=" + _linkEndpoint + + '}'; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/AmqpErrorException.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/AmqpErrorException.java new file mode 100644 index 0000000000..74ae7de470 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/AmqpErrorException.java @@ -0,0 +1,54 @@ +/* + * + * 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.amqp_1_0.type; + +import org.apache.qpid.amqp_1_0.type.transport.Error; + +import java.util.Formatter; + +public class AmqpErrorException extends Exception +{ + private final Error _error; + + + public AmqpErrorException(final Error error) + { + _error = error; + } + + public AmqpErrorException(ErrorCondition condition) + { + _error = new Error(); + _error.setCondition(condition); + } + + public AmqpErrorException(ErrorCondition condition, String format, Object... args) + { + _error = new Error(); + _error.setCondition(condition); + _error.setDescription((new Formatter()).format(format, args).toString()); + } + + public Error getError() + { + return _error; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Binary.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Binary.java new file mode 100644 index 0000000000..0c8dc3444a --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Binary.java @@ -0,0 +1,161 @@ +/* + * + * 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.amqp_1_0.type; + +import java.nio.ByteBuffer; +import java.util.Collection; + +import static java.lang.Math.min; + +public class Binary +{ + + private final byte[] _data; + private final int _offset; + private final int _length; + private final int _hashCode; + + public Binary(final byte[] data) + { + this(data, 0, data.length); + } + + public Binary(final byte[] data, final int offset, final int length) + { + + _data = data; + _offset = offset; + _length = length; + int hc = 0; + for (int i = 0; i < length; i++) + { + hc = 31*hc + (0xFF & data[offset + i]); + } + _hashCode = hc; + } + + public ByteBuffer asByteBuffer() + { + return ByteBuffer.wrap(_data, _offset, _length); + } + + public final int hashCode() + { + return _hashCode; + } + + public final boolean equals(Object o) + { + Binary buf = (Binary) o; + if(o == null) + { + return false; + } + final int size = _length; + if (size != buf._length) + { + return false; + } + + final byte[] myData = _data; + final byte[] theirData = buf._data; + int myOffset = _offset; + int theirOffset = buf._offset; + final int myLimit = myOffset + size; + + while(myOffset < myLimit) + { + if (myData[myOffset++] != theirData[theirOffset++]) + { + return false; + } + } + + return true; + } + + + public int getArrayOffset() + { + return _offset; + } + + public byte[] getArray() + { + return _data; + } + + public int getLength() + { + return _length; + } + + public String toString() + { + StringBuilder str = new StringBuilder(); + + + for (int i = _offset; i < _length; i++) + { + byte c = _data[i]; + + if (c > 31 && c < 127 && c != '\\') + { + str.append((char)c); + } + else + { + str.append(String.format("\\x%02x", c)); + } + } + + return str.toString(); + + } + + public static Binary combine(final Collection binaries) + { + + if(binaries.size() == 1) + { + return binaries.iterator().next(); + } + + int size = 0; + for(Binary binary : binaries) + { + size += binary.getLength(); + } + byte[] data = new byte[size]; + int offset = 0; + for(Binary binary : binaries) + { + System.arraycopy(binary._data, binary._offset, data, offset, binary._length); + offset += binary._length; + } + return new Binary(data); + } + + public Binary subBinary(final int offset, final int length) + { + return new Binary(_data, _offset+offset, length); + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DeliveryState.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DeliveryState.java new file mode 100644 index 0000000000..a16cc46729 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DeliveryState.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface DeliveryState +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DistributionMode.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DistributionMode.java new file mode 100644 index 0000000000..751bdd1406 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DistributionMode.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface DistributionMode +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/ErrorCondition.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/ErrorCondition.java new file mode 100644 index 0000000000..a9f8115784 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/ErrorCondition.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.amqp_1_0.type; + +public interface ErrorCondition +{ + public Symbol getValue(); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/FrameBody.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/FrameBody.java new file mode 100644 index 0000000000..0312378019 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/FrameBody.java @@ -0,0 +1,29 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.amqp_1_0.type; + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + +public interface FrameBody +{ + public void invoke(short channel, ConnectionEndpoint conn); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/GlobalTxId.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/GlobalTxId.java new file mode 100644 index 0000000000..f17a8648c6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/GlobalTxId.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public class GlobalTxId +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/LifetimePolicy.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/LifetimePolicy.java new file mode 100644 index 0000000000..af13cdaffe --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/LifetimePolicy.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface LifetimePolicy +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Outcome.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Outcome.java new file mode 100644 index 0000000000..0741ebdf70 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Outcome.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface Outcome +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/RestrictedType.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/RestrictedType.java new file mode 100644 index 0000000000..9bcfc752a1 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/RestrictedType.java @@ -0,0 +1,26 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.amqp_1_0.type; + +public interface RestrictedType +{ + V getValue(); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/SaslFrameBody.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/SaslFrameBody.java new file mode 100644 index 0000000000..cb4332f020 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/SaslFrameBody.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.amqp_1_0.type; + +import org.apache.qpid.amqp_1_0.transport.SASLEndpoint; + +public interface SaslFrameBody +{ + public void invoke(SASLEndpoint conn); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Section.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Section.java new file mode 100644 index 0000000000..1e2872b66a --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Section.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.amqp_1_0.type; + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + +public interface Section +{ + + Binary encode(SectionEncoder encoder); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Source.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Source.java new file mode 100644 index 0000000000..c033ed4d55 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Source.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface Source +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Symbol.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Symbol.java new file mode 100644 index 0000000000..6efcdcf952 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Symbol.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.amqp_1_0.type; + +import java.util.concurrent.ConcurrentHashMap; + +public final class Symbol implements Comparable, CharSequence +{ + private final String _underlying; + private static final ConcurrentHashMap _symbols = new ConcurrentHashMap(2048); + + private Symbol(String underlying) + { + _underlying = underlying; + } + + public int length() + { + return _underlying.length(); + } + + public int compareTo(Symbol o) + { + return _underlying.compareTo(o._underlying); + } + + public char charAt(int index) + { + return _underlying.charAt(index); + } + + public CharSequence subSequence(int beginIndex, int endIndex) + { + return _underlying.subSequence(beginIndex, endIndex); + } + + @Override + public String toString() + { + return _underlying; + } + + @Override + public int hashCode() + { + return _underlying.hashCode(); + } + + public static Symbol valueOf(String symbolVal) + { + return getSymbol(symbolVal); + } + + public static Symbol getSymbol(String symbolVal) + { + Symbol symbol = _symbols.get(symbolVal); + if(symbol == null) + { + symbolVal = symbolVal.intern(); + symbol = new Symbol(symbolVal); + Symbol existing; + if((existing = _symbols.putIfAbsent(symbolVal, symbol)) != null) + { + symbol = existing; + } + } + return symbol; + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Target.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Target.java new file mode 100644 index 0000000000..345f6c418f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Target.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface Target +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnCapability.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnCapability.java new file mode 100644 index 0000000000..3d7d2137a6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnCapability.java @@ -0,0 +1,26 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + +package org.apache.qpid.amqp_1_0.type; + +public interface TxnCapability +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnId.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnId.java new file mode 100644 index 0000000000..eef6b3a32f --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnId.java @@ -0,0 +1,23 @@ +/* + * 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.amqp_1_0.type; + +public interface TxnId +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedByte.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedByte.java new file mode 100644 index 0000000000..07739e068e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedByte.java @@ -0,0 +1,134 @@ +/* + * + * 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.amqp_1_0.type; + +public final class UnsignedByte extends Number implements Comparable +{ + private final byte _underlying; + private static final UnsignedByte[] cachedValues = new UnsignedByte[256]; + + static + { + for(int i = 0; i<256; i++) + { + cachedValues[i] = new UnsignedByte((byte)i); + } + } + + public UnsignedByte(byte underlying) + { + _underlying = underlying; + } + + @Override + public byte byteValue() + { + return _underlying; + } + + @Override + public short shortValue() + { + return (short) intValue(); + } + + @Override + public int intValue() + { + return ((int)_underlying) & 0xFF; + } + + @Override + public long longValue() + { + return ((long) _underlying) & 0xFFl; + } + + @Override + public float floatValue() + { + return (float) longValue(); + } + + @Override + public double doubleValue() + { + return (double) longValue(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + UnsignedByte that = (UnsignedByte) o; + + if (_underlying != that._underlying) + { + return false; + } + + return true; + } + + public int compareTo(UnsignedByte o) + { + return Integer.signum(intValue() - o.intValue()); + } + + @Override + public int hashCode() + { + return _underlying; + } + + @Override + public String toString() + { + return String.valueOf(intValue()); + } + + public static UnsignedByte valueOf(byte underlying) + { + final int index = ((int) underlying) & 0xFF; + return cachedValues[index]; + } + + public static UnsignedByte valueOf(final String value) + throws NumberFormatException + { + int intVal = Integer.parseInt(value); + if(intVal < 0 || intVal >= (1<<8)) + { + throw new NumberFormatException("Value \""+value+"\" lies outside the range [" + 0 + "-" + (1<<8) +")."); + } + return valueOf((byte)intVal); + } + +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedInteger.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedInteger.java new file mode 100644 index 0000000000..f9a8f96868 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedInteger.java @@ -0,0 +1,149 @@ +/* + * + * 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.amqp_1_0.type; + +public final class UnsignedInteger extends Number implements Comparable +{ + private final int _underlying; + private static final UnsignedInteger[] cachedValues = new UnsignedInteger[256]; + + static + { + for(int i = 0; i < 256; i++) + { + cachedValues[i] = new UnsignedInteger(i); + } + } + + public static final UnsignedInteger ZERO = cachedValues[0]; + public static final UnsignedInteger ONE = cachedValues[1]; + public static final UnsignedInteger MAX_VALUE = new UnsignedInteger(0xffffffff); + + + public UnsignedInteger(int underlying) + { + _underlying = underlying; + } + + @Override + public int intValue() + { + return _underlying; + } + + @Override + public long longValue() + { + return ((long) _underlying) & 0xFFFFFFFFl; + } + + @Override + public float floatValue() + { + return (float) longValue(); + } + + @Override + public double doubleValue() + { + return (double) longValue(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + UnsignedInteger that = (UnsignedInteger) o; + + if (_underlying != that._underlying) + { + return false; + } + + return true; + } + + public int compareTo(UnsignedInteger o) + { + return Long.signum(longValue() - o.longValue()); + } + + @Override + public int hashCode() + { + return _underlying; + } + + @Override + public String toString() + { + return String.valueOf(longValue()); + } + + public static UnsignedInteger valueOf(int underlying) + { + if((underlying & 0xFFFFFF00) == 0) + { + return cachedValues[underlying]; + } + else + { + return new UnsignedInteger(underlying); + } + } + + public UnsignedInteger add(final UnsignedInteger i) + { + int val = _underlying + i._underlying; + return UnsignedInteger.valueOf(val); + } + + public UnsignedInteger subtract(final UnsignedInteger i) + { + int val = _underlying - i._underlying; + return UnsignedInteger.valueOf(val); + } + + public static UnsignedInteger valueOf(final String value) + { + long longVal = Long.parseLong(value); + return valueOf(longVal); + } + + public static UnsignedInteger valueOf(final long longVal) + { + if(longVal < 0L || longVal >= (1L<<32)) + { + throw new NumberFormatException("Value \""+longVal+"\" lies outside the range [" + 0L + "-" + (1L<<32) +")."); + } + return valueOf((int)longVal); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedLong.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedLong.java new file mode 100644 index 0000000000..0586423fe0 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedLong.java @@ -0,0 +1,162 @@ +/* + * + * 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.amqp_1_0.type; + +import java.math.BigInteger; + +public final class UnsignedLong extends Number implements Comparable +{ + private static final BigInteger TWO_TO_THE_SIXTY_FOUR = new BigInteger( new byte[] { (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0 }); + private static final BigInteger LONG_MAX_VALUE = BigInteger.valueOf(Long.MAX_VALUE); + + private static final UnsignedLong[] cachedValues = new UnsignedLong[256]; + + static + { + for(int i = 0; i<256; i++) + { + cachedValues[i] = new UnsignedLong(i); + } + } + + public static final UnsignedLong ZERO = cachedValues[0]; + public static final UnsignedLong ONE = cachedValues[1]; + + private final long _underlying; + + + + public UnsignedLong(long underlying) + { + _underlying = underlying; + } + + @Override + public int intValue() + { + return (int) _underlying; + } + + @Override + public long longValue() + { + return _underlying; + } + + public BigInteger bigIntegerValue() + { + if(_underlying >= 0L) + { + return BigInteger.valueOf(_underlying); + } + else + { + return TWO_TO_THE_SIXTY_FOUR.add(BigInteger.valueOf(_underlying)); + } + } + + @Override + public float floatValue() + { + return (float) longValue(); + } + + @Override + public double doubleValue() + { + return (double) longValue(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + UnsignedLong that = (UnsignedLong) o; + + if (_underlying != that._underlying) + { + return false; + } + + return true; + } + + public int compareTo(UnsignedLong o) + { + return bigIntegerValue().compareTo(o.bigIntegerValue()); + } + + @Override + public int hashCode() + { + return (int)(_underlying ^ (_underlying >>> 32)); + } + + @Override + public String toString() + { + return String.valueOf(bigIntegerValue()); + } + + public static UnsignedLong valueOf(long underlying) + { + if((underlying & 0xFFL) == underlying) + { + return cachedValues[(int)underlying]; + } + else + { + return new UnsignedLong(underlying); + } + } + + public static UnsignedLong valueOf(final String value) + { + BigInteger bigInt = new BigInteger(value); + if(bigInt.signum() == -1 || bigInt.bitCount()>64) + { + throw new NumberFormatException("Value \""+value+"\" lies outside the range [" + 0L + "- 2^64)."); + } + else if(bigInt.compareTo(LONG_MAX_VALUE)>=0) + { + return UnsignedLong.valueOf(bigInt.longValue()); + } + else + { + return UnsignedLong.valueOf(TWO_TO_THE_SIXTY_FOUR.subtract(bigInt).negate().longValue()); + } + + } + + public UnsignedLong add(UnsignedLong unsignedLong) + { + return UnsignedLong.valueOf(_underlying + unsignedLong._underlying); + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedShort.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedShort.java new file mode 100644 index 0000000000..01c72ac159 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedShort.java @@ -0,0 +1,132 @@ +/* + * + * 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.amqp_1_0.type; + +public final class UnsignedShort extends Number implements Comparable +{ + private final short _underlying; + private static final UnsignedShort[] cachedValues = new UnsignedShort[256]; + + static + { + for(short i = 0; i < 256; i++) + { + cachedValues[i] = new UnsignedShort(i); + } + } + + public UnsignedShort(short underlying) + { + _underlying = underlying; + } + + public short shortValue() + { + return _underlying; + } + + @Override + public int intValue() + { + return _underlying & 0xFFFF; + } + + @Override + public long longValue() + { + return ((long) _underlying) & 0xFFFFl; + } + + @Override + public float floatValue() + { + return (float) intValue(); + } + + @Override + public double doubleValue() + { + return (double) intValue(); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + UnsignedShort that = (UnsignedShort) o; + + if (_underlying != that._underlying) + { + return false; + } + + return true; + } + + public int compareTo(UnsignedShort o) + { + return Integer.signum(intValue() - o.intValue()); + } + + @Override + public int hashCode() + { + return _underlying; + } + + @Override + public String toString() + { + return String.valueOf(longValue()); + } + + public static UnsignedShort valueOf(short underlying) + { + if((underlying & 0xFF00) == 0) + { + return cachedValues[underlying]; + } + else + { + return new UnsignedShort(underlying); + } + } + + public static UnsignedShort valueOf(final String value) + { + int intVal = Integer.parseInt(value); + if(intVal < 0 || intVal >= (1<<16)) + { + throw new NumberFormatException("Value \""+value+"\" lies outside the range [" + 0 + "-" + (1<<16) +")."); + } + return valueOf((short)intVal); + + } +} \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/WrapperType.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/WrapperType.java new file mode 100644 index 0000000000..359926d9d4 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/WrapperType.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.amqp_1_0.type; + +public interface WrapperType +{ + Object getValue(); +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/codec/AMQPDescribedTypeRegistry.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/codec/AMQPDescribedTypeRegistry.java new file mode 100644 index 0000000000..5ffa96e094 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/codec/AMQPDescribedTypeRegistry.java @@ -0,0 +1,389 @@ + + +package org.apache.qpid.amqp_1_0.type.codec; + +import org.apache.qpid.amqp_1_0.codec.BinaryWriter; +import org.apache.qpid.amqp_1_0.codec.BooleanWriter; +import org.apache.qpid.amqp_1_0.codec.ByteWriter; +import org.apache.qpid.amqp_1_0.codec.CharWriter; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.codec.DoubleWriter; +import org.apache.qpid.amqp_1_0.codec.FloatWriter; +import org.apache.qpid.amqp_1_0.codec.IntegerWriter; +import org.apache.qpid.amqp_1_0.codec.ListWriter; +import org.apache.qpid.amqp_1_0.codec.LongWriter; +import org.apache.qpid.amqp_1_0.codec.MapWriter; +import org.apache.qpid.amqp_1_0.codec.NullWriter; +import org.apache.qpid.amqp_1_0.codec.RestrictedTypeValueWriter; +import org.apache.qpid.amqp_1_0.codec.ShortWriter; +import org.apache.qpid.amqp_1_0.codec.StringWriter; +import org.apache.qpid.amqp_1_0.codec.SymbolWriter; +import org.apache.qpid.amqp_1_0.codec.SymbolArrayWriter; +import org.apache.qpid.amqp_1_0.codec.TimestampWriter; +import org.apache.qpid.amqp_1_0.codec.TypeConstructor; +import org.apache.qpid.amqp_1_0.codec.UUIDWriter; +import org.apache.qpid.amqp_1_0.codec.UnsignedByteWriter; +import org.apache.qpid.amqp_1_0.codec.UnsignedIntegerWriter; +import org.apache.qpid.amqp_1_0.codec.UnsignedLongWriter; +import org.apache.qpid.amqp_1_0.codec.UnsignedShortWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + + +import org.apache.qpid.amqp_1_0.type.RestrictedType; +import org.apache.qpid.amqp_1_0.type.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.codec.*; + +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.codec.*; + +import org.apache.qpid.amqp_1_0.type.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.codec.*; + +import org.apache.qpid.amqp_1_0.type.security.*; +import org.apache.qpid.amqp_1_0.type.security.codec.*; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class AMQPDescribedTypeRegistry implements DescribedTypeConstructorRegistry, ValueWriter.Registry +{ + + private final Map _constructorRegistry = new HashMap(); + + public void register(Object descriptor, DescribedTypeConstructor constructor) + { + _constructorRegistry.put(descriptor, constructor); + } + + public void register(Object descriptor, DescribedTypeConstructor constructor, TypeConstructor describedConstructor) + { + _constructorRegistry.put(descriptor, constructor); + } + + public DescribedTypeConstructor getConstructor(Object descriptor) + { + return _constructorRegistry.get(descriptor); + } + + private AMQPDescribedTypeRegistry() + { + } + + public AMQPDescribedTypeRegistry registerTransportLayer() + { + registerTransportConstructors(this); + registerTransportWriters(this); + return this; + } + + public AMQPDescribedTypeRegistry registerMessagingLayer() + { + registerMessagingConstructors(this); + registerMessagingWriters(this); + return this; + } + + public AMQPDescribedTypeRegistry registerTransactionLayer() + { + registerTransactionsConstructors(this); + registerTransactionsWriters(this); + return this; + } + + public AMQPDescribedTypeRegistry registerSecurityLayer() + { + registerSecurityConstructors(this); + registerSecurityWriters(this); + return this; + } + + public static AMQPDescribedTypeRegistry newInstance() + { + AMQPDescribedTypeRegistry registry = new AMQPDescribedTypeRegistry(); + + NullWriter.register(registry); + BooleanWriter.register(registry); + ByteWriter.register(registry); + UnsignedByteWriter.register(registry); + ShortWriter.register(registry); + UnsignedShortWriter.register(registry); + IntegerWriter.register(registry); + UnsignedIntegerWriter.register(registry); + CharWriter.register(registry); + FloatWriter.register(registry); + LongWriter.register(registry); + UnsignedLongWriter.register(registry); + DoubleWriter.register(registry); + TimestampWriter.register(registry); + UUIDWriter.register(registry); + StringWriter.register(registry); + SymbolWriter.register(registry); + BinaryWriter.register(registry); + ListWriter.register(registry); + MapWriter.register(registry); + + SymbolArrayWriter.register(registry); + + return registry; + } + + + + private static void registerTransportWriters(final AMQPDescribedTypeRegistry registry) + { + + OpenWriter.register(registry); + BeginWriter.register(registry); + AttachWriter.register(registry); + FlowWriter.register(registry); + TransferWriter.register(registry); + DispositionWriter.register(registry); + DetachWriter.register(registry); + EndWriter.register(registry); + CloseWriter.register(registry); + RestrictedTypeValueWriter.register(registry,Role.class); + RestrictedTypeValueWriter.register(registry,SenderSettleMode.class); + RestrictedTypeValueWriter.register(registry,ReceiverSettleMode.class); + ErrorWriter.register(registry); + RestrictedTypeValueWriter.register(registry,AmqpError.class); + RestrictedTypeValueWriter.register(registry,ConnectionError.class); + RestrictedTypeValueWriter.register(registry,SessionError.class); + RestrictedTypeValueWriter.register(registry,LinkError.class); + } + + private static void registerMessagingWriters(final AMQPDescribedTypeRegistry registry) + { + + HeaderWriter.register(registry); + DeliveryAnnotationsWriter.register(registry); + MessageAnnotationsWriter.register(registry); + PropertiesWriter.register(registry); + ApplicationPropertiesWriter.register(registry); + DataWriter.register(registry); + AmqpSequenceWriter.register(registry); + AmqpValueWriter.register(registry); + FooterWriter.register(registry); + ReceivedWriter.register(registry); + AcceptedWriter.register(registry); + RejectedWriter.register(registry); + ReleasedWriter.register(registry); + ModifiedWriter.register(registry); + SourceWriter.register(registry); + TargetWriter.register(registry); + RestrictedTypeValueWriter.register(registry,TerminusDurability.class); + RestrictedTypeValueWriter.register(registry,TerminusExpiryPolicy.class); + RestrictedTypeValueWriter.register(registry,StdDistMode.class); + DeleteOnCloseWriter.register(registry); + DeleteOnNoLinksWriter.register(registry); + DeleteOnNoMessagesWriter.register(registry); + DeleteOnNoLinksOrMessagesWriter.register(registry); + + + ExactSubjectFilterWriter.register(registry); + MatchingSubjectFilterWriter.register(registry); + JMSSelectorFilterWriter.register(registry); + NoLocalFilterWriter.register(registry); + } + + private static void registerTransactionsWriters(final AMQPDescribedTypeRegistry registry) + { + + CoordinatorWriter.register(registry); + DeclareWriter.register(registry); + DischargeWriter.register(registry); + DeclaredWriter.register(registry); + TransactionalStateWriter.register(registry); + RestrictedTypeValueWriter.register(registry,TxnCapability.class); + RestrictedTypeValueWriter.register(registry,TransactionErrors.class); + } + + private static void registerSecurityWriters(final AMQPDescribedTypeRegistry registry) + { + + SaslMechanismsWriter.register(registry); + SaslInitWriter.register(registry); + SaslChallengeWriter.register(registry); + SaslResponseWriter.register(registry); + SaslOutcomeWriter.register(registry); + RestrictedTypeValueWriter.register(registry,SaslCode.class); + } + + private static void registerTransportConstructors(final AMQPDescribedTypeRegistry registry) + { + + OpenConstructor.register(registry); + BeginConstructor.register(registry); + AttachConstructor.register(registry); + FlowConstructor.register(registry); + TransferConstructor.register(registry); + DispositionConstructor.register(registry); + DetachConstructor.register(registry); + EndConstructor.register(registry); + CloseConstructor.register(registry); + ErrorConstructor.register(registry); + } + + private static void registerMessagingConstructors(final AMQPDescribedTypeRegistry registry) + { + + HeaderConstructor.register(registry); + DeliveryAnnotationsConstructor.register(registry); + MessageAnnotationsConstructor.register(registry); + PropertiesConstructor.register(registry); + ApplicationPropertiesConstructor.register(registry); + DataConstructor.register(registry); + AmqpSequenceConstructor.register(registry); + AmqpValueConstructor.register(registry); + FooterConstructor.register(registry); + ReceivedConstructor.register(registry); + AcceptedConstructor.register(registry); + RejectedConstructor.register(registry); + ReleasedConstructor.register(registry); + ModifiedConstructor.register(registry); + SourceConstructor.register(registry); + TargetConstructor.register(registry); + DeleteOnCloseConstructor.register(registry); + DeleteOnNoLinksConstructor.register(registry); + DeleteOnNoMessagesConstructor.register(registry); + DeleteOnNoLinksOrMessagesConstructor.register(registry); + + ExactSubjectFilterConstructor.register(registry); + MatchingSubjectFilterConstructor.register(registry); + JMSSelectorFilterConstructor.register(registry); + NoLocalFilterConstructor.register(registry); + } + + private static void registerTransactionsConstructors(final AMQPDescribedTypeRegistry registry) + { + + CoordinatorConstructor.register(registry); + DeclareConstructor.register(registry); + DischargeConstructor.register(registry); + DeclaredConstructor.register(registry); + TransactionalStateConstructor.register(registry); + } + + private static void registerSecurityConstructors(final AMQPDescribedTypeRegistry registry) + { + + SaslMechanismsConstructor.register(registry); + SaslInitConstructor.register(registry); + SaslChallengeConstructor.register(registry); + SaslResponseConstructor.register(registry); + SaslOutcomeConstructor.register(registry); + } + + + private final Map _writerMap = new HashMap(); + private final Map _cachedWriters = new HashMap(); + + public ValueWriter getValueWriter(V value, Map localCache) + { + Class clazz = value == null ? Void.TYPE : value.getClass(); + ValueWriter writer = null; // TODO localCache.get(clazz); + if(writer == null || !writer.isComplete()) + { + writer = getValueWriter(value); + localCache.put(clazz, writer); + } + else + { + writer.setValue(value); + } + + + return writer; + } + + + public ValueWriter getValueWriter(V value) + { + + Class clazz = value == null ? Void.TYPE : value.getClass(); + + ValueWriter writer = null; // TODO _cachedWriters.get(clazz); + if(writer == null || !writer.isComplete()) + { + ValueWriter.Factory factory = (ValueWriter.Factory) (_writerMap.get(clazz)); + + if(factory == null) + { + if(value instanceof List) + { + factory = _writerMap.get(List.class); + _writerMap.put(value.getClass(), factory); + writer = factory.newInstance(this); + if(writer.isCacheable()) + { + _cachedWriters.put(clazz, writer); + } + writer.setValue(value); + + } + else if(value instanceof Map) + { + factory = _writerMap.get(Map.class); + _writerMap.put(value.getClass(), factory); + writer = factory.newInstance(this); + if(writer.isCacheable()) + { + _cachedWriters.put(clazz, writer); + } + writer.setValue(value); + + } + else if(value.getClass().isArray()) + { + if(RestrictedType.class.isAssignableFrom(value.getClass().getComponentType())) + { + RestrictedType[] restrictedTypes = (RestrictedType[]) value; + Object[] newVals = (Object[]) Array.newInstance(restrictedTypes[0].getValue().getClass(), + restrictedTypes.length); + for(int i = 0; i < restrictedTypes.length; i++) + { + newVals[i] = restrictedTypes[i].getValue(); + } + return (ValueWriter) getValueWriter(newVals); + } + // TODO primitive array types + factory = _writerMap.get(List.class); + writer = factory.newInstance(this); + writer.setValue(Arrays.asList((Object[])value)); + + } + else + { + return null; + } + } + else + { + writer = factory.newInstance(this); + if(writer.isCacheable()) + { + _cachedWriters.put(clazz, writer); + } + writer.setValue(value); + } + } + else + { + writer.setValue(value); + } + + return writer; + + } + + public ValueWriter register(Class clazz, ValueWriter.Factory writer) + { + return (ValueWriter) _writerMap.put(clazz, writer); + } + +} + + \ No newline at end of file diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Accepted.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Accepted.java new file mode 100644 index 0000000000..aede9df82e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Accepted.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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Accepted + implements org.apache.qpid.amqp_1_0.type.DeliveryState, Outcome + { + + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Accepted{"); + final int origLength = builder.length(); + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpSequence.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpSequence.java new file mode 100644 index 0000000000..72531f3acc --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpSequence.java @@ -0,0 +1,70 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import java.util.List; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class AmqpSequence + implements Section + { + + + + private final List _value; + + public AmqpSequence(List value) + { + _value = value; + } + + public List getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + @Override + public String toString() + { + return "AmqpSequence{" + + _value + + '}'; + } + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpValue.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpValue.java new file mode 100644 index 0000000000..22723decca --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpValue.java @@ -0,0 +1,66 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class AmqpValue + implements Section + { + + + + private final Object _value; + + public AmqpValue(Object value) + { + _value = value; + } + + public Object getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + @Override + public String toString() + { + return "AmqpValue{(" + _value.getClass().getName() + ')' + _value + '}'; + } + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ApplicationProperties.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ApplicationProperties.java new file mode 100644 index 0000000000..fb9200ecb6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ApplicationProperties.java @@ -0,0 +1,64 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class ApplicationProperties + implements Section + { + + + + private final Map _value; + + public ApplicationProperties(Map value) + { + _value = value; + } + + public Map getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Data.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Data.java new file mode 100644 index 0000000000..f4b8b78264 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Data.java @@ -0,0 +1,68 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Data + implements Section + { + + + + private final Binary _value; + + public Data(Binary value) + { + _value = value; + } + + public Binary getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + @Override + public String toString() + { + return "Data{" + + _value + + '}'; + } + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnClose.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnClose.java new file mode 100644 index 0000000000..aab5cf8a27 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnClose.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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class DeleteOnClose + implements LifetimePolicy + { + + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("DeleteOnClose{"); + final int origLength = builder.length(); + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinks.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinks.java new file mode 100644 index 0000000000..ab0043ea5b --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinks.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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class DeleteOnNoLinks + implements LifetimePolicy + { + + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("DeleteOnNoLinks{"); + final int origLength = builder.length(); + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinksOrMessages.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinksOrMessages.java new file mode 100644 index 0000000000..591597c655 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinksOrMessages.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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class DeleteOnNoLinksOrMessages + implements LifetimePolicy + { + + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("DeleteOnNoLinksOrMessages{"); + final int origLength = builder.length(); + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoMessages.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoMessages.java new file mode 100644 index 0000000000..9e44061928 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoMessages.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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class DeleteOnNoMessages + implements LifetimePolicy + { + + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("DeleteOnNoMessages{"); + final int origLength = builder.length(); + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeliveryAnnotations.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeliveryAnnotations.java new file mode 100644 index 0000000000..bde1da090e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeliveryAnnotations.java @@ -0,0 +1,64 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class DeliveryAnnotations + implements Section + { + + + + private final Map _value; + + public DeliveryAnnotations(Map value) + { + _value = value; + } + + public Map getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ExactSubjectFilter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ExactSubjectFilter.java new file mode 100644 index 0000000000..3d01a26485 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ExactSubjectFilter.java @@ -0,0 +1,82 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; + +public class ExactSubjectFilter implements Filter +{ + + + + private final String _value; + + public ExactSubjectFilter(String value) + { + _value = value; + } + + public String getValue() + { + return _value; + } + + + @Override + public String toString() + { + return "ExactSubjectFilter{" + _value + '}'; + } + + @Override + public boolean equals(Object o) + { + if(this == o) + { + return true; + } + if(o == null || getClass() != o.getClass()) + { + return false; + } + + ExactSubjectFilter that = (ExactSubjectFilter) o; + + if(_value != null ? !_value.equals(that._value) : that._value != null) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + return _value != null ? _value.hashCode() : 0; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Filter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Filter.java new file mode 100644 index 0000000000..46f391bf4d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Filter.java @@ -0,0 +1,28 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + +public interface Filter +{ +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Footer.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Footer.java new file mode 100644 index 0000000000..25cf04763e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Footer.java @@ -0,0 +1,70 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Footer + implements Section + { + + + + private final Map _value; + + public Footer(Map value) + { + _value = value; + } + + public Map getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + @Override + public String toString() + { + return "Footer{" + _value + + '}'; + } + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Header.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Header.java new file mode 100644 index 0000000000..02b4810196 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Header.java @@ -0,0 +1,161 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Header + implements Section + { + + + private Boolean _durable; + + private UnsignedByte _priority; + + private UnsignedInteger _ttl; + + private Boolean _firstAcquirer; + + private UnsignedInteger _deliveryCount; + + public Boolean getDurable() + { + return _durable; + } + + public void setDurable(Boolean durable) + { + _durable = durable; + } + + public UnsignedByte getPriority() + { + return _priority; + } + + public void setPriority(UnsignedByte priority) + { + _priority = priority; + } + + public UnsignedInteger getTtl() + { + return _ttl; + } + + public void setTtl(UnsignedInteger ttl) + { + _ttl = ttl; + } + + public Boolean getFirstAcquirer() + { + return _firstAcquirer; + } + + public void setFirstAcquirer(Boolean firstAcquirer) + { + _firstAcquirer = firstAcquirer; + } + + public UnsignedInteger getDeliveryCount() + { + return _deliveryCount; + } + + public void setDeliveryCount(UnsignedInteger deliveryCount) + { + _deliveryCount = deliveryCount; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Header{"); + final int origLength = builder.length(); + + if(_durable != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("durable=").append(_durable); + } + + if(_priority != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("priority=").append(_priority); + } + + if(_ttl != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("ttl=").append(_ttl); + } + + if(_firstAcquirer != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("firstAcquirer=").append(_firstAcquirer); + } + + if(_deliveryCount != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("deliveryCount=").append(_deliveryCount); + } + + builder.append('}'); + return builder.toString(); + } + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/JMSSelectorFilter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/JMSSelectorFilter.java new file mode 100644 index 0000000000..a6317c42bf --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/JMSSelectorFilter.java @@ -0,0 +1,77 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +public class JMSSelectorFilter implements Filter +{ + + + + private final String _value; + + public JMSSelectorFilter(String value) + { + _value = value; + } + + public String getValue() + { + return _value; + } + + @Override + public String toString() + { + return "JMSSelector{" + _value + '}'; + } + + @Override + public boolean equals(Object o) + { + if(this == o) + { + return true; + } + if(o == null || getClass() != o.getClass()) + { + return false; + } + + JMSSelectorFilter that = (JMSSelectorFilter) o; + + if(_value != null ? !_value.equals(that._value) : that._value != null) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + return _value != null ? _value.hashCode() : 0; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MatchingSubjectFilter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MatchingSubjectFilter.java new file mode 100644 index 0000000000..9504a658a9 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MatchingSubjectFilter.java @@ -0,0 +1,81 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.Section; + +public class MatchingSubjectFilter implements Filter +{ + + + + private final String _value; + + public MatchingSubjectFilter(String value) + { + _value = value; + } + + public String getValue() + { + return _value; + } + + @Override + public String toString() + { + return "MatchingSubjectFilter{" + _value + '}'; + } + + @Override + public boolean equals(Object o) + { + if(this == o) + { + return true; + } + if(o == null || getClass() != o.getClass()) + { + return false; + } + + MatchingSubjectFilter that = (MatchingSubjectFilter) o; + + if(_value != null ? !_value.equals(that._value) : that._value != null) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + return _value != null ? _value.hashCode() : 0; + } +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MessageAnnotations.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MessageAnnotations.java new file mode 100644 index 0000000000..265beb7213 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MessageAnnotations.java @@ -0,0 +1,64 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class MessageAnnotations + implements Section + { + + + + private final Map _value; + + public MessageAnnotations(Map value) + { + _value = value; + } + + public Map getValue() + { + return _value; + } + + + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Modified.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Modified.java new file mode 100644 index 0000000000..d466cbf2b1 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Modified.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.amqp_1_0.type.messaging; + + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Modified + implements org.apache.qpid.amqp_1_0.type.DeliveryState, Outcome + { + + + private Boolean _deliveryFailed; + + private Boolean _undeliverableHere; + + private Map _messageAnnotations; + + public Boolean getDeliveryFailed() + { + return _deliveryFailed; + } + + public void setDeliveryFailed(Boolean deliveryFailed) + { + _deliveryFailed = deliveryFailed; + } + + public Boolean getUndeliverableHere() + { + return _undeliverableHere; + } + + public void setUndeliverableHere(Boolean undeliverableHere) + { + _undeliverableHere = undeliverableHere; + } + + public Map getMessageAnnotations() + { + return _messageAnnotations; + } + + public void setMessageAnnotations(Map messageAnnotations) + { + _messageAnnotations = messageAnnotations; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Modified{"); + final int origLength = builder.length(); + + if(_deliveryFailed != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("deliveryFailed=").append(_deliveryFailed); + } + + if(_undeliverableHere != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("undeliverableHere=").append(_undeliverableHere); + } + + if(_messageAnnotations != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("messageAnnotations=").append(_messageAnnotations); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/NoLocalFilter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/NoLocalFilter.java new file mode 100644 index 0000000000..73f175e6fa --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/NoLocalFilter.java @@ -0,0 +1,45 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +public final class NoLocalFilter implements Filter +{ + + + public static final NoLocalFilter INSTANCE = new NoLocalFilter(); + + private NoLocalFilter() + { + } + + + @Override + public String toString() + { + return "NoLocalFilter{}"; + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Properties.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Properties.java new file mode 100644 index 0000000000..bcab361a8e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Properties.java @@ -0,0 +1,333 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + +import org.apache.qpid.amqp_1_0.messaging.SectionEncoder; + + +import java.util.Date; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Properties + implements Section + { + + + private Object _messageId; + + private Binary _userId; + + private String _to; + + private String _subject; + + private String _replyTo; + + private Object _correlationId; + + private Symbol _contentType; + + private Symbol _contentEncoding; + + private Date _absoluteExpiryTime; + + private Date _creationTime; + + private String _groupId; + + private UnsignedInteger _groupSequence; + + private String _replyToGroupId; + + public Object getMessageId() + { + return _messageId; + } + + public void setMessageId(Object messageId) + { + _messageId = messageId; + } + + public Binary getUserId() + { + return _userId; + } + + public void setUserId(Binary userId) + { + _userId = userId; + } + + public String getTo() + { + return _to; + } + + public void setTo(String to) + { + _to = to; + } + + public String getSubject() + { + return _subject; + } + + public void setSubject(String subject) + { + _subject = subject; + } + + public String getReplyTo() + { + return _replyTo; + } + + public void setReplyTo(String replyTo) + { + _replyTo = replyTo; + } + + public Object getCorrelationId() + { + return _correlationId; + } + + public void setCorrelationId(Object correlationId) + { + _correlationId = correlationId; + } + + public Symbol getContentType() + { + return _contentType; + } + + public void setContentType(Symbol contentType) + { + _contentType = contentType; + } + + public Symbol getContentEncoding() + { + return _contentEncoding; + } + + public void setContentEncoding(Symbol contentEncoding) + { + _contentEncoding = contentEncoding; + } + + public Date getAbsoluteExpiryTime() + { + return _absoluteExpiryTime; + } + + public void setAbsoluteExpiryTime(Date absoluteExpiryTime) + { + _absoluteExpiryTime = absoluteExpiryTime; + } + + public Date getCreationTime() + { + return _creationTime; + } + + public void setCreationTime(Date creationTime) + { + _creationTime = creationTime; + } + + public String getGroupId() + { + return _groupId; + } + + public void setGroupId(String groupId) + { + _groupId = groupId; + } + + public UnsignedInteger getGroupSequence() + { + return _groupSequence; + } + + public void setGroupSequence(UnsignedInteger groupSequence) + { + _groupSequence = groupSequence; + } + + public String getReplyToGroupId() + { + return _replyToGroupId; + } + + public void setReplyToGroupId(String replyToGroupId) + { + _replyToGroupId = replyToGroupId; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Properties{"); + final int origLength = builder.length(); + + if(_messageId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("messageId=").append(_messageId); + } + + if(_userId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("userId=").append(_userId); + } + + if(_to != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("to=").append(_to); + } + + if(_subject != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("subject=").append(_subject); + } + + if(_replyTo != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("replyTo=").append(_replyTo); + } + + if(_correlationId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("correlationId=").append(_correlationId); + } + + if(_contentType != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("contentType=").append(_contentType); + } + + if(_contentEncoding != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("contentEncoding=").append(_contentEncoding); + } + + if(_absoluteExpiryTime != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("absoluteExpiryTime=").append(_absoluteExpiryTime); + } + + if(_creationTime != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("creationTime=").append(_creationTime); + } + + if(_groupId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("groupId=").append(_groupId); + } + + if(_groupSequence != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("groupSequence=").append(_groupSequence); + } + + if(_replyToGroupId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("replyToGroupId=").append(_replyToGroupId); + } + + builder.append('}'); + return builder.toString(); + } + + + public Binary encode(final SectionEncoder encoder) + { + encoder.reset(); + encoder.encodeObject(this); + return encoder.getEncoding(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Received.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Received.java new file mode 100644 index 0000000000..2e398063b8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Received.java @@ -0,0 +1,88 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Received + implements org.apache.qpid.amqp_1_0.type.DeliveryState + { + + + private UnsignedInteger _sectionNumber; + + private UnsignedLong _sectionOffset; + + public UnsignedInteger getSectionNumber() + { + return _sectionNumber; + } + + public void setSectionNumber(UnsignedInteger sectionNumber) + { + _sectionNumber = sectionNumber; + } + + public UnsignedLong getSectionOffset() + { + return _sectionOffset; + } + + public void setSectionOffset(UnsignedLong sectionOffset) + { + _sectionOffset = sectionOffset; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Received{"); + final int origLength = builder.length(); + + if(_sectionNumber != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("sectionNumber=").append(_sectionNumber); + } + + if(_sectionOffset != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("sectionOffset=").append(_sectionOffset); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Rejected.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Rejected.java new file mode 100644 index 0000000000..c895074131 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Rejected.java @@ -0,0 +1,70 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.transport.Error; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Rejected + implements org.apache.qpid.amqp_1_0.type.DeliveryState, Outcome + { + + + private Error _error; + + public Error getError() + { + return _error; + } + + public void setError(Error error) + { + _error = error; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Rejected{"); + final int origLength = builder.length(); + + if(_error != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("error=").append(_error); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Released.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Released.java new file mode 100644 index 0000000000..ad54b6ff04 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Released.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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Released + implements org.apache.qpid.amqp_1_0.type.DeliveryState, Outcome + { + + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Released{"); + final int origLength = builder.length(); + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Source.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Source.java new file mode 100644 index 0000000000..b634542fd6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Source.java @@ -0,0 +1,280 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Source + implements org.apache.qpid.amqp_1_0.type.Source + { + + + private String _address; + + private TerminusDurability _durable; + + private TerminusExpiryPolicy _expiryPolicy; + + private UnsignedInteger _timeout; + + private Boolean _dynamic; + + private Map _dynamicNodeProperties; + + private DistributionMode _distributionMode; + + private Map _filter; + + private Outcome _defaultOutcome; + + private Symbol[] _outcomes; + + private Symbol[] _capabilities; + + public String getAddress() + { + return _address; + } + + public void setAddress(String address) + { + _address = address; + } + + public TerminusDurability getDurable() + { + return _durable; + } + + public void setDurable(TerminusDurability durable) + { + _durable = durable; + } + + public TerminusExpiryPolicy getExpiryPolicy() + { + return _expiryPolicy; + } + + public void setExpiryPolicy(TerminusExpiryPolicy expiryPolicy) + { + _expiryPolicy = expiryPolicy; + } + + public UnsignedInteger getTimeout() + { + return _timeout; + } + + public void setTimeout(UnsignedInteger timeout) + { + _timeout = timeout; + } + + public Boolean getDynamic() + { + return _dynamic; + } + + public void setDynamic(Boolean dynamic) + { + _dynamic = dynamic; + } + + public Map getDynamicNodeProperties() + { + return _dynamicNodeProperties; + } + + public void setDynamicNodeProperties(Map dynamicNodeProperties) + { + _dynamicNodeProperties = dynamicNodeProperties; + } + + public DistributionMode getDistributionMode() + { + return _distributionMode; + } + + public void setDistributionMode(DistributionMode distributionMode) + { + _distributionMode = distributionMode; + } + + public Map getFilter() + { + return _filter; + } + + public void setFilter(Map filter) + { + _filter = filter; + } + + public Outcome getDefaultOutcome() + { + return _defaultOutcome; + } + + public void setDefaultOutcome(Outcome defaultOutcome) + { + _defaultOutcome = defaultOutcome; + } + + public Symbol[] getOutcomes() + { + return _outcomes; + } + + public void setOutcomes(Symbol[] outcomes) + { + _outcomes = outcomes; + } + + public Symbol[] getCapabilities() + { + return _capabilities; + } + + public void setCapabilities(Symbol[] capabilities) + { + _capabilities = capabilities; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Source{"); + final int origLength = builder.length(); + + if(_address != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("address=").append(_address); + } + + if(_durable != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("durable=").append(_durable); + } + + if(_expiryPolicy != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("expiryPolicy=").append(_expiryPolicy); + } + + if(_timeout != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("timeout=").append(_timeout); + } + + if(_dynamic != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("dynamic=").append(_dynamic); + } + + if(_dynamicNodeProperties != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("dynamicNodeProperties=").append(_dynamicNodeProperties); + } + + if(_distributionMode != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("distributionMode=").append(_distributionMode); + } + + if(_filter != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("filter=").append(_filter); + } + + if(_defaultOutcome != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("defaultOutcome=").append(_defaultOutcome); + } + + if(_outcomes != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("outcomes=").append(_outcomes); + } + + if(_capabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("capabilities=").append(_capabilities); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/StdDistMode.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/StdDistMode.java new file mode 100644 index 0000000000..a3fba6fe46 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/StdDistMode.java @@ -0,0 +1,95 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class StdDistMode + implements DistributionMode, RestrictedType + + { + + + + private final Symbol _val; + + + public static final StdDistMode MOVE = new StdDistMode(Symbol.valueOf("move")); + + public static final StdDistMode COPY = new StdDistMode(Symbol.valueOf("copy")); + + + + private StdDistMode(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == MOVE) + { + return "move"; + } + + if(this == COPY) + { + return "copy"; + } + + else + { + return String.valueOf(_val); + } + } + + public static StdDistMode valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(MOVE._val.equals(val)) + { + return MOVE; + } + + if(COPY._val.equals(val)) + { + return COPY; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Target.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Target.java new file mode 100644 index 0000000000..ea9319d31d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Target.java @@ -0,0 +1,196 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Target + implements org.apache.qpid.amqp_1_0.type.Target + { + + + private String _address; + + private TerminusDurability _durable; + + private TerminusExpiryPolicy _expiryPolicy; + + private UnsignedInteger _timeout; + + private Boolean _dynamic; + + private Map _dynamicNodeProperties; + + private Symbol[] _capabilities; + + public String getAddress() + { + return _address; + } + + public void setAddress(String address) + { + _address = address; + } + + public TerminusDurability getDurable() + { + return _durable; + } + + public void setDurable(TerminusDurability durable) + { + _durable = durable; + } + + public TerminusExpiryPolicy getExpiryPolicy() + { + return _expiryPolicy; + } + + public void setExpiryPolicy(TerminusExpiryPolicy expiryPolicy) + { + _expiryPolicy = expiryPolicy; + } + + public UnsignedInteger getTimeout() + { + return _timeout; + } + + public void setTimeout(UnsignedInteger timeout) + { + _timeout = timeout; + } + + public Boolean getDynamic() + { + return _dynamic; + } + + public void setDynamic(Boolean dynamic) + { + _dynamic = dynamic; + } + + public Map getDynamicNodeProperties() + { + return _dynamicNodeProperties; + } + + public void setDynamicNodeProperties(Map dynamicNodeProperties) + { + _dynamicNodeProperties = dynamicNodeProperties; + } + + public Symbol[] getCapabilities() + { + return _capabilities; + } + + public void setCapabilities(Symbol[] capabilities) + { + _capabilities = capabilities; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Target{"); + final int origLength = builder.length(); + + if(_address != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("address=").append(_address); + } + + if(_durable != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("durable=").append(_durable); + } + + if(_expiryPolicy != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("expiryPolicy=").append(_expiryPolicy); + } + + if(_timeout != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("timeout=").append(_timeout); + } + + if(_dynamic != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("dynamic=").append(_dynamic); + } + + if(_dynamicNodeProperties != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("dynamicNodeProperties=").append(_dynamicNodeProperties); + } + + if(_capabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("capabilities=").append(_capabilities); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusDurability.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusDurability.java new file mode 100644 index 0000000000..b08c416b4a --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusDurability.java @@ -0,0 +1,107 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class TerminusDurability + implements RestrictedType + + { + + + + private final UnsignedInteger _val; + + + public static final TerminusDurability NONE = new TerminusDurability(UnsignedInteger.valueOf(0)); + + public static final TerminusDurability CONFIGURATION = new TerminusDurability(UnsignedInteger.valueOf(1)); + + public static final TerminusDurability UNSETTLED_STATE = new TerminusDurability(UnsignedInteger.valueOf(2)); + + + + private TerminusDurability(UnsignedInteger val) + { + _val = val; + } + + public UnsignedInteger getValue() + { + return _val; + } + + public String toString() + { + + if(this == NONE) + { + return "none"; + } + + if(this == CONFIGURATION) + { + return "configuration"; + } + + if(this == UNSETTLED_STATE) + { + return "unsettled-state"; + } + + else + { + return String.valueOf(_val); + } + } + + public static TerminusDurability valueOf(Object obj) + { + UnsignedInteger val = (UnsignedInteger) obj; + + if(NONE._val.equals(val)) + { + return NONE; + } + + if(CONFIGURATION._val.equals(val)) + { + return CONFIGURATION; + } + + if(UNSETTLED_STATE._val.equals(val)) + { + return UNSETTLED_STATE; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusExpiryPolicy.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusExpiryPolicy.java new file mode 100644 index 0000000000..7ed2f84532 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusExpiryPolicy.java @@ -0,0 +1,119 @@ + +/* +* +* 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.amqp_1_0.type.messaging; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class TerminusExpiryPolicy + implements RestrictedType + + { + + + + private final Symbol _val; + + + public static final TerminusExpiryPolicy LINK_DETACH = new TerminusExpiryPolicy(Symbol.valueOf("link-detach")); + + public static final TerminusExpiryPolicy SESSION_END = new TerminusExpiryPolicy(Symbol.valueOf("session-end")); + + public static final TerminusExpiryPolicy CONNECTION_CLOSE = new TerminusExpiryPolicy(Symbol.valueOf("connection-close")); + + public static final TerminusExpiryPolicy NEVER = new TerminusExpiryPolicy(Symbol.valueOf("never")); + + + + private TerminusExpiryPolicy(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == LINK_DETACH) + { + return "link-detach"; + } + + if(this == SESSION_END) + { + return "session-end"; + } + + if(this == CONNECTION_CLOSE) + { + return "connection-close"; + } + + if(this == NEVER) + { + return "never"; + } + + else + { + return String.valueOf(_val); + } + } + + public static TerminusExpiryPolicy valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(LINK_DETACH._val.equals(val)) + { + return LINK_DETACH; + } + + if(SESSION_END._val.equals(val)) + { + return SESSION_END; + } + + if(CONNECTION_CLOSE._val.equals(val)) + { + return CONNECTION_CLOSE; + } + + if(NEVER._val.equals(val)) + { + return NEVER; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedConstructor.java new file mode 100644 index 0000000000..8000853a4d --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedConstructor.java @@ -0,0 +1,72 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Accepted; + + +import java.util.List; + +public class AcceptedConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:accepted:list"),UnsignedLong.valueOf(0x0000000000000024L), + }; + + private static final AcceptedConstructor INSTANCE = new AcceptedConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Accepted construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Accepted obj = new Accepted(); + int position = 0; + final int size = list.size(); + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedWriter.java new file mode 100644 index 0000000000..862b678b59 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedWriter.java @@ -0,0 +1,151 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.AbstractListWriter; +import org.apache.qpid.amqp_1_0.codec.ListWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.Accepted; + +public class AcceptedWriter extends AbstractDescribedTypeWriter +{ + private Accepted _value; + private int _count = -1; + + public AcceptedWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Accepted value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000024L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + if(_count != 0) + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + else + { + return new ListWriter.EmptyListValueWriter(); + } + + } + + private class Writer extends AbstractListWriter + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Accepted value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new AcceptedWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Accepted.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceConstructor.java new file mode 100644 index 0000000000..7304a50b18 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceConstructor.java @@ -0,0 +1,68 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpSequence; + + +import java.util.List; + +public class AmqpSequenceConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:amqp-sequence:list"),UnsignedLong.valueOf(0x0000000000000076L), + }; + + private static final AmqpSequenceConstructor INSTANCE = new AmqpSequenceConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public AmqpSequence construct(Object underlying) + { + + if(underlying instanceof List) + { + return new AmqpSequence((List)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceWriter.java new file mode 100644 index 0000000000..14c10ca5e6 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceWriter.java @@ -0,0 +1,80 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpSequence; + +public class AmqpSequenceWriter extends AbstractDescribedTypeWriter +{ + private AmqpSequence _value; + + + + public AmqpSequenceWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final AmqpSequence value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000076L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new AmqpSequenceWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(AmqpSequence.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueConstructor.java new file mode 100644 index 0000000000..2000880361 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueConstructor.java @@ -0,0 +1,65 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; + +public class AmqpValueConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:amqp-value:*"),UnsignedLong.valueOf(0x0000000000000077L), + }; + + private static final AmqpValueConstructor INSTANCE = new AmqpValueConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public AmqpValue construct(Object underlying) + { + + if(underlying instanceof Object) + { + return new AmqpValue((Object)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueWriter.java new file mode 100644 index 0000000000..f38d2edb00 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueWriter.java @@ -0,0 +1,80 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpValue; + +public class AmqpValueWriter extends AbstractDescribedTypeWriter +{ + private AmqpValue _value; + + + + public AmqpValueWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final AmqpValue value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000077L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new AmqpValueWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(AmqpValue.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesConstructor.java new file mode 100644 index 0000000000..f2bf26b7b4 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesConstructor.java @@ -0,0 +1,68 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties; + + +import java.util.Map; + +public class ApplicationPropertiesConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:application-properties:map"),UnsignedLong.valueOf(0x0000000000000074L), + }; + + private static final ApplicationPropertiesConstructor INSTANCE = new ApplicationPropertiesConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public ApplicationProperties construct(Object underlying) + { + + if(underlying instanceof Map) + { + return new ApplicationProperties((Map)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesWriter.java new file mode 100644 index 0000000000..6fff917058 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesWriter.java @@ -0,0 +1,80 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.ApplicationProperties; + +public class ApplicationPropertiesWriter extends AbstractDescribedTypeWriter +{ + private ApplicationProperties _value; + + + + public ApplicationPropertiesWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final ApplicationProperties value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000074L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ApplicationPropertiesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(ApplicationProperties.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataConstructor.java new file mode 100644 index 0000000000..75e921c1b8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataConstructor.java @@ -0,0 +1,65 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Data; + +public class DataConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:data:binary"),UnsignedLong.valueOf(0x0000000000000075L), + }; + + private static final DataConstructor INSTANCE = new DataConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public Data construct(Object underlying) + { + + if(underlying instanceof Binary) + { + return new Data((Binary)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataWriter.java new file mode 100644 index 0000000000..5ae6eecb43 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataWriter.java @@ -0,0 +1,80 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.Data; + +public class DataWriter extends AbstractDescribedTypeWriter +{ + private Data _value; + + + + public DataWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Data value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000075L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DataWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Data.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseConstructor.java new file mode 100644 index 0000000000..31236a00cc --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseConstructor.java @@ -0,0 +1,72 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnClose; + + +import java.util.List; + +public class DeleteOnCloseConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:delete-on-close:list"),UnsignedLong.valueOf(0x000000000000002bL), + }; + + private static final DeleteOnCloseConstructor INSTANCE = new DeleteOnCloseConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public DeleteOnClose construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + DeleteOnClose obj = new DeleteOnClose(); + int position = 0; + final int size = list.size(); + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseWriter.java new file mode 100644 index 0000000000..3ea43f2565 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseWriter.java @@ -0,0 +1,142 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.AbstractListWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnClose; + +public class DeleteOnCloseWriter extends AbstractDescribedTypeWriter +{ + private DeleteOnClose _value; + private int _count = -1; + + public DeleteOnCloseWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnClose value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x000000000000002bL); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnClose value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DeleteOnCloseWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnClose.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksConstructor.java new file mode 100644 index 0000000000..e5ea6e923e --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksConstructor.java @@ -0,0 +1,72 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnNoLinks; + + +import java.util.List; + +public class DeleteOnNoLinksConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:delete-on-no-links:list"),UnsignedLong.valueOf(0x000000000000002cL), + }; + + private static final DeleteOnNoLinksConstructor INSTANCE = new DeleteOnNoLinksConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public DeleteOnNoLinks construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + DeleteOnNoLinks obj = new DeleteOnNoLinks(); + int position = 0; + final int size = list.size(); + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesConstructor.java new file mode 100644 index 0000000000..c9bafe9550 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesConstructor.java @@ -0,0 +1,72 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnNoLinksOrMessages; + + +import java.util.List; + +public class DeleteOnNoLinksOrMessagesConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:delete-on-no-links-or-messages:list"),UnsignedLong.valueOf(0x000000000000002eL), + }; + + private static final DeleteOnNoLinksOrMessagesConstructor INSTANCE = new DeleteOnNoLinksOrMessagesConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public DeleteOnNoLinksOrMessages construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + DeleteOnNoLinksOrMessages obj = new DeleteOnNoLinksOrMessages(); + int position = 0; + final int size = list.size(); + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesWriter.java new file mode 100644 index 0000000000..e77c6a3be4 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesWriter.java @@ -0,0 +1,142 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.AbstractListWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnNoLinksOrMessages; + +public class DeleteOnNoLinksOrMessagesWriter extends AbstractDescribedTypeWriter +{ + private DeleteOnNoLinksOrMessages _value; + private int _count = -1; + + public DeleteOnNoLinksOrMessagesWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnNoLinksOrMessages value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x000000000000002eL); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnNoLinksOrMessages value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DeleteOnNoLinksOrMessagesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnNoLinksOrMessages.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksWriter.java new file mode 100644 index 0000000000..cbd5048ba1 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksWriter.java @@ -0,0 +1,142 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.AbstractListWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnNoLinks; + +public class DeleteOnNoLinksWriter extends AbstractDescribedTypeWriter +{ + private DeleteOnNoLinks _value; + private int _count = -1; + + public DeleteOnNoLinksWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnNoLinks value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x000000000000002cL); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnNoLinks value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DeleteOnNoLinksWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnNoLinks.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesConstructor.java new file mode 100644 index 0000000000..de8ce5b9a5 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesConstructor.java @@ -0,0 +1,72 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnNoMessages; + + +import java.util.List; + +public class DeleteOnNoMessagesConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:delete-on-no-messages:list"),UnsignedLong.valueOf(0x000000000000002dL), + }; + + private static final DeleteOnNoMessagesConstructor INSTANCE = new DeleteOnNoMessagesConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public DeleteOnNoMessages construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + DeleteOnNoMessages obj = new DeleteOnNoMessages(); + int position = 0; + final int size = list.size(); + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesWriter.java new file mode 100644 index 0000000000..bd75ec9fa1 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesWriter.java @@ -0,0 +1,142 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.AbstractListWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.DeleteOnNoMessages; + +public class DeleteOnNoMessagesWriter extends AbstractDescribedTypeWriter +{ + private DeleteOnNoMessages _value; + private int _count = -1; + + public DeleteOnNoMessagesWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnNoMessages value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x000000000000002dL); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeleteOnNoMessages value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DeleteOnNoMessagesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnNoMessages.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsConstructor.java new file mode 100644 index 0000000000..3596a1f722 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsConstructor.java @@ -0,0 +1,68 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations; + + +import java.util.Map; + +public class DeliveryAnnotationsConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:delivery-annotations:map"),UnsignedLong.valueOf(0x0000000000000071L), + }; + + private static final DeliveryAnnotationsConstructor INSTANCE = new DeliveryAnnotationsConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public DeliveryAnnotations construct(Object underlying) + { + + if(underlying instanceof Map) + { + return new DeliveryAnnotations((Map)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsWriter.java new file mode 100644 index 0000000000..e22c26b290 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsWriter.java @@ -0,0 +1,80 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; + +import org.apache.qpid.amqp_1_0.type.UnsignedLong; +import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations; + +public class DeliveryAnnotationsWriter extends AbstractDescribedTypeWriter +{ + private DeliveryAnnotations _value; + + + + public DeliveryAnnotationsWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final DeliveryAnnotations value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000071L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new DeliveryAnnotationsWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeliveryAnnotations.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterConstructor.java new file mode 100644 index 0000000000..90eff967b2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterConstructor.java @@ -0,0 +1,64 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.ExactSubjectFilter; + +public class ExactSubjectFilterConstructor extends DescribedTypeConstructor +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("apache.org:legacy-amqp-direct-binding:string"), 0x0000468C00000000L + }; + + private static final ExactSubjectFilterConstructor INSTANCE = new ExactSubjectFilterConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public ExactSubjectFilter construct(Object underlying) + { + + if(underlying instanceof String) + { + return new ExactSubjectFilter((String)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterWriter.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterWriter.java new file mode 100644 index 0000000000..2e95aba7a2 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterWriter.java @@ -0,0 +1,78 @@ + +/* +* +* 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.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.AbstractDescribedTypeWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.type.messaging.ExactSubjectFilter; + +public class ExactSubjectFilterWriter extends AbstractDescribedTypeWriter +{ + private ExactSubjectFilter _value; + + + + public ExactSubjectFilterWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final ExactSubjectFilter value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return 0x0000468C00000000L; + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory FACTORY = new Factory() + { + + public ValueWriter newInstance(Registry registry) + { + return new ExactSubjectFilterWriter(registry); + } + }; + + public static void register(Registry registry) + { + registry.register(ExactSubjectFilter.class, FACTORY); + } + +} diff --git a/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterConstructor.java b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterConstructor.java new file mode 100644 index 0000000000..ed92c9f8f8 --- /dev/null +++ b/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterConstructor.java @@ -0,0 +1,68 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.messaging.codec; + +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructor; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.messaging.*; +import org.apache.qpid.amqp_1_0.type.messaging.Footer; + + +import java.util.Map; + +public class FooterConstructor extends DescribedTypeConstructor