diff options
| author | Robert Godfrey <rgodfrey@apache.org> | 2012-04-04 21:10:07 +0000 |
|---|---|---|
| committer | Robert Godfrey <rgodfrey@apache.org> | 2012-04-04 21:10:07 +0000 |
| commit | e70c313cebf1c11ef77b32c0766a69a2d66cd134 (patch) | |
| tree | ab7be312ee56b53ed17bcac0f0565c485a5a6fd4 | |
| parent | 2db8073cfd87aff6ac64de3128f1ebb2952ca0db (diff) | |
| download | qpid-python-e70c313cebf1c11ef77b32c0766a69a2d66cd134.tar.gz | |
QPID-3933 : [Java] Add interim AMQP 1-0 implementation
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1309594 13f79535-47bb-0310-9956-ffa450edef68
461 files changed, 54580 insertions, 94 deletions
diff --git a/qpid/java/amqp-1-0-client-jms/build.xml b/qpid/java/amqp-1-0-client-jms/build.xml new file mode 100644 index 0000000000..4a685d7106 --- /dev/null +++ b/qpid/java/amqp-1-0-client-jms/build.xml @@ -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. + - + --> +<project name="AMQP 1.0 JMS Client" default="build"> + + <property name="module.genpom" value="true"/> + <property name="module.depends" value="amqp-1-0-common amqp-1-0-client"/> + + + <import file="../module.xml"/> + +</project> diff --git a/qpid/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/Hello.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/example/src/main/java/org/apache/qpid/amqp_1_0/jms/example/hello.properties b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/AmqpMessage.java b/qpid/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/qpid/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<Section> sectionIterator();
+}
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/BytesMessage.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Connection.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionFactory.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ConnectionMetaData.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Destination.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/JavaSerializable.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MapMessage.java b/qpid/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/qpid/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<Object> keySet() throws JMSException;
+
+}
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Message.java b/qpid/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/qpid/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<Object> getListProperty(Object name) throws JMSException;
+
+ Map<Object,Object> 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<Object> list) throws JMSException;
+
+ void setMapProperty(Object name, Map<Object,Object> 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageConsumer.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/MessageProducer.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/ObjectMessage.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Queue.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueBrowser.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueConnection.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueReceiver.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSender.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/QueueSession.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Session.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/StreamMessage.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryDestination.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryQueue.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TemporaryTopic.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TextMessage.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/Topic.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicConnection.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicPublisher.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSession.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/TopicSubscriber.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/AmqpMessageImpl.java b/qpid/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/qpid/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<Section> _sections;
+
+ protected AmqpMessageImpl(Header header, MessageAnnotations messageAnnotations, Properties properties, ApplicationProperties appProperties, List<Section> 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<Section>();
+ }
+
+ public int getSectionCount()
+ {
+ return _sections.size();
+ }
+
+ public Section getSection(final int position)
+ {
+ return _sections.get(position);
+ }
+
+ public ListIterator<Section> sectionIterator()
+ {
+ return _sections.listIterator();
+ }
+
+ @Override Collection<Section> getSections()
+ {
+ List<Section> sections = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/BytesMessageImpl.java b/qpid/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/qpid/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<Section> getSections()
+ {
+ List<Section> sections = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java b/qpid/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..66bf91a53f --- /dev/null +++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionFactoryImpl.java @@ -0,0 +1,167 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either 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.ConnectionFactory; + +import javax.jms.JMSException; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import java.net.MalformedURLException; +import java.net.URL; + +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, + 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionImpl.java b/qpid/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/qpid/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<SessionImpl> _sessions = new ArrayList<SessionImpl>();
+
+ 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<CloseTask> _closeTasks = new ArrayList<CloseTask>();
+
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ConnectionMetaDataImpl.java b/qpid/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/qpid/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<String> _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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/DestinationImpl.java b/qpid/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/qpid/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<String, DestinationImpl> DESTINATION_CACHE =
+ new WeakHashMap<String, DestinationImpl>();
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MapMessageImpl.java b/qpid/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/qpid/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<Object> 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<Section> getSections()
+ {
+ List<Section> sections = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageConsumerImpl.java b/qpid/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..dcea8f6771 --- /dev/null +++ b/qpid/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<Binary> _txnMsgs = Collections.synchronizedCollection(new ArrayList<Binary>());
+ private Binary _lastTxnUpdate;
+ private final List<Message> _recoverReplayMessages = new ArrayList<Message>();
+ private final List<Message> _replaymessages = new ArrayList<Message>();
+
+ 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())
+ && error.getInfo() != null && Symbol.valueOf("filter").equals(error.getInfo().get(Symbol.valueOf
+ ("field"))))
+ {
+ throw new InvalidSelectorException(e.getMessage());
+ }
+ else
+ {
+ throw new JMSException(e.getMessage(), error.getCondition().getValue().toString());
+
+ }
+ }
+ }
+
+ Map<Symbol, Filter> 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<Symbol, Filter> filters = new HashMap<Symbol, Filter>();
+ 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)
+ {
+ _receiver.updateAll(new Modified(), _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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageFactory.java b/qpid/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/qpid/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<Section> payload = msg.getPayload();
+ Header header = null;
+ MessageAnnotations messageAnnotations = null;
+
+ Properties properties = null;
+ ApplicationProperties appProperties = null;
+ Footer footer;
+
+ Iterator<Section> iter = payload.iterator();
+ List<Section> body = new ArrayList<Section>();
+
+ 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<Object> data = new ArrayList<Object>();
+
+ ListIterator<Object> 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageImpl.java b/qpid/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..96798b69a1 --- /dev/null +++ b/qpid/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<Class> _supportedClasses =
+ new HashSet<Class>(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("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)
+ {
+ setDeliveryFailures(UnsignedInteger.valueOf(1));
+ }
+ }
+ 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<Object> getListProperty(final Object name) throws JMSException
+ {
+ Object value = getProperty(name);
+ if(value instanceof List || value == null)
+ {
+ return (List<Object>)value;
+ }
+ else
+ {
+ throw new MessageFormatException("Property " + name + " of type " + value.getClass().getName()
+ + " cannot be converted to List.");
+ }
+ }
+
+ public Map<Object, Object> getMapProperty(final Object name) throws JMSException
+ {
+ Object value = getProperty(name);
+ if(value instanceof Map || value == null)
+ {
+ return (Map<Object,Object>)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<String> names = new ArrayList<String>();
+ 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<Object> list) throws JMSException
+ {
+ _applicationProperties.getValue().put(name, list);
+ }
+
+ public void setMapProperty(final Object name, final Map<Object, Object> 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<Section> getSections();
+}
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/MessageProducerImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/ObjectMessageImpl.java b/qpid/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/qpid/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<Section> getSections()
+ {
+ List<Section> sections = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java b/qpid/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..a068ca7a08 --- /dev/null +++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueBrowserImpl.java @@ -0,0 +1,144 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either 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.jms.QueueBrowser;
+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.DistributionMode;
+import org.apache.qpid.amqp_1_0.type.Outcome;
+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;
+
+import javax.jms.InvalidSelectorException;
+import javax.jms.JMSException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Map;
+
+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<Symbol, Filter> 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())
+ && error.getInfo() != null && Symbol.valueOf("filter").equals(error.getInfo().get(Symbol.valueOf
+ ("field"))))
+ {
+ 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<Message>
+ {
+
+ @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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueConnectionImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueImpl.java b/qpid/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/qpid/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<String, QueueImpl> QUEUE_CACHE =
+ new WeakHashMap<String, QueueImpl>();
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueReceiverImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSenderImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/QueueSessionImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java b/qpid/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..08a6ac6f20 --- /dev/null +++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/SessionImpl.java @@ -0,0 +1,885 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either 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.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.Target;
+import org.apache.qpid.amqp_1_0.type.transport.AmqpError;
+
+import javax.jms.*;
+import javax.jms.BytesMessage;
+import javax.jms.Destination;
+import javax.jms.IllegalStateException;
+import javax.jms.MapMessage;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.UUID;
+
+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<MessageConsumerImpl> _consumers = new ArrayList<MessageConsumerImpl>();
+ private List<MessageProducerImpl> _producers = new ArrayList<MessageProducerImpl>();
+
+ 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);
+ 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<MessageConsumerImpl> _messageConsumerList = new ArrayList<MessageConsumerImpl>();
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/StreamMessageImpl.java b/qpid/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/qpid/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<Section> getSections()
+ {
+ List<Section> sections = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryQueueImpl.java b/qpid/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/qpid/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<MessageConsumer> _consumers =
+ Collections.synchronizedSet(new HashSet<MessageConsumer>());
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TemporaryTopicImpl.java b/qpid/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/qpid/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<MessageConsumer> _consumers =
+ Collections.synchronizedSet(new HashSet<MessageConsumer>());
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TextMessageImpl.java b/qpid/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/qpid/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<Section> getSections()
+ {
+ List<Section> sections = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicConnectionImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicImpl.java b/qpid/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/qpid/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<String, TopicImpl> TOPIC_CACHE =
+ new WeakHashMap<String, TopicImpl>();
+
+
+ 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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicPublisherImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSessionImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java b/qpid/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..374a4c1ef8 --- /dev/null +++ b/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/impl/TopicSubscriberImpl.java @@ -0,0 +1,127 @@ +/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either 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<Symbol, Filter> actualFilters = (Map<Symbol, Filter>) receiver.getFilter();
+
+ if(!address.equals(actualAddress) || !filtersEqual(getFilters(), actualFilters))
+ {
+ 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())
+ && error.getInfo() != null && Symbol.valueOf("filter").equals(error.getInfo().get(Symbol.valueOf
+ ("field"))))
+ {
+ throw new InvalidSelectorException(e.getMessage());
+ }
+ else
+ {
+ throw new JMSException(e.getMessage(), error.getCondition().getValue().toString());
+
+ }
+
+ }
+ }
+
+ private boolean filtersEqual(Map<Symbol, Filter> filters, Map<Symbol, Filter> actualFilters)
+ {
+ if(filters == null || filters.isEmpty())
+ {
+ return actualFilters == null || actualFilters.isEmpty();
+ }
+ else
+ {
+ return actualFilters != null && filters.equals(actualFilters);
+ }
+
+ }
+
+
+ protected void closeUnderlyingReceiver(Receiver receiver)
+ {
+ receiver.detach();
+ }
+}
diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/NameParserImpl.java b/qpid/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/qpid/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} + * <p/> + * Based on class from ActiveMQ. + */ +public class NameParserImpl implements NameParser +{ + public Name parse(String name) throws NamingException + { + return new CompositeName(name); + } +} diff --git a/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/PropertiesFileInitialContextFactory.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client-jms/src/main/java/org/apache/qpid/amqp_1_0/jms/jndi/ReadOnlyContext.java b/qpid/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/qpid/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 + * <p/> + * 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. + * </p> + * <p>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:</p> + * <code> + * Context componentContext = (Context)new InitialContext().lookup("java:comp"); + * String envEntry = (String) componentContext.lookup("env/myEntry"); + * String envEntry2 = (String) componentContext.lookup("env/myEntry2"); + * </code> + */ +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/qpid/java/amqp-1-0-client/build.xml b/qpid/java/amqp-1-0-client/build.xml new file mode 100644 index 0000000000..173d7540d4 --- /dev/null +++ b/qpid/java/amqp-1-0-client/build.xml @@ -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. + - + --> +<project name="AMQP 1.0 Client" default="build"> + + <property name="module.genpom" value="true"/> + <property name="module.depends" value="amqp-1-0-common"/> + + + <import file="../module.xml"/> + +</project> diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/AcknowledgeMode.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Command.java b/qpid/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/qpid/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<Util> clazz = (Class<Util>) Class.forName(name); + Util util = clazz.getDeclaredConstructor(String[].class).newInstance((Object)cmdArgs); + util.run(); + + } +} diff --git a/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Connection.java b/qpid/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/qpid/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<FrameBody> out = new ConnectionHandler.FrameOutput<FrameBody>(_conn);
+
+
+ final OutputStream outputStream = s.getOutputStream();
+
+ ConnectionHandler.BytesSource src;
+
+ if(_conn.requiresSASL())
+ {
+ ConnectionHandler.FrameOutput<SaslFrameBody> saslOut = new ConnectionHandler.FrameOutput<SaslFrameBody>(_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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Demo.java b/qpid/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/qpid/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] <vendor> [<content> ...]\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<Object, Sender> sendingLinks = new HashMap<Object, Sender>();
+ Map<Object, Receiver> receivingLinks = new HashMap<Object, Receiver>();
+
+
+ boolean done = false;
+
+ while(!done)
+ {
+ boolean wait = true;
+ Message m = responseReceiver.receive(false);
+ if(m != null)
+ {
+ List<Section> 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<Object, Receiver> 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Dump.java b/qpid/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/qpid/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] <address>\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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filereceiver.java b/qpid/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/qpid/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] <address> <directory>\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<Binary, Outcome> unsettled = new HashMap<Binary, Outcome>(); + final Map<Binary, String> unsettledFileNames = new HashMap<Binary, String>(); + + 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<Binary, Outcome> remoteUnsettled = r.getRemoteUnsettled(); + + for(Map.Entry<Binary, String> 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<Section> 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<Binary> data = new ArrayList<Binary>(); + 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Filesender.java b/qpid/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/qpid/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] <address> <directory>\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<Binary, Outcome> unsettled = new HashMap<Binary, Outcome>(); + Map<Binary, String> unsettledFileNames = new HashMap<Binary, String>(); + 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<Binary, DeliveryState> remoteUnsettled = s.getRemoteUnsettled(); + + for(Map.Entry<Binary, String> 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<Binary, DeliveryState> 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Message.java b/qpid/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/qpid/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<Section> _payload = new ArrayList<Section>();
+ private Boolean _resume;
+ private boolean _settled;
+ private DeliveryState _deliveryState;
+ private Receiver _receiver;
+
+
+ public Message()
+ {
+ }
+
+ public Message(Collection<Section> 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<Section> getPayload()
+ {
+ return Collections.unmodifiableList(_payload);
+ }
+
+ private <T extends Section> T getSection(Class<T> 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/ReadBytes.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receive.java b/qpid/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/qpid/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] <address> \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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java new file mode 100644 index 0000000000..c5b3cd35ab --- /dev/null +++ b/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Receiver.java @@ -0,0 +1,548 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either 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<Transfer> _prefetchQueue = new ConcurrentLinkedQueue<Transfer>();
+ private Map<Binary, SettledAction> _unsettledMap = new HashMap<Binary, SettledAction>();
+ 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<Binary,Outcome> unsettled) throws AmqpErrorException
+ {
+
+ _session = session;
+ if(isDurable)
+ {
+ source.setDurable(TerminusDurability.UNSETTLED_STATE);
+ source.setExpiryPolicy(TerminusExpiryPolicy.NEVER);
+ }
+ _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<Section> sections = new ArrayList<Section>();
+ List<ByteBuffer> payloads = new ArrayList<ByteBuffer>();
+ 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)
+ {
+ update(new Modified(), 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<Binary, Outcome> getRemoteUnsettled()
+ {
+ return _endpoint.getInitialUnsettledMap();
+ }
+
+
+ public void setMessageArrivalListener(final MessageArrivalListener messageArrivalListener)
+ {
+ synchronized(_endpoint.getLock())
+ {
+ _messageArrivalListener = messageArrivalListener;
+ }
+ }
+
+ public Session getSession()
+ {
+ return _session;
+ }
+
+ 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Request.java b/qpid/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/qpid/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] <address> [<content> ...]\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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Respond.java b/qpid/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/qpid/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] <address>\n\nOptions:"; + private Connection _conn; + private Session _session; + private Receiver _receiver; + private Transaction _txn; + private Map<String,Sender> _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<String, Sender>(); + + 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<Message> txnMessages = null; + if(useTran()) + { + if(getRollbackRatio() != 0) + { + random = new Random(); + } + batch = getBatchSize(); + _txn = _session.createSessionLocalTransaction(); + txnMessages = new ArrayList<Message>(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<getRollbackRatio()) + { + _txn.rollback(); + } + else + { + _txn.commit(); + txnMessages.clear(); + receivedCount += getBatchSize(); + } + } + while(result < getRollbackRatio()); + } + _txn = _session.createSessionLocalTransaction(); + + batch = getBatchSize(); + } + } + else + { + receivedCount++; + } + + } + + + for(Sender s : _senders.values()) + { + s.close(); + } + + _receiver.close(); + _session.close(); + _conn.close(); + System.out.println("Received: " + receivedCount); + } + 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. + } + } + + private void respond(Message m) throws Sender.SenderCreationException + { + List<Section> 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<Section> replySections = new ArrayList<Section>(sections); + + ListIterator<Section> 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Send.java b/qpid/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/qpid/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] <address> [<content> ...]\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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/SendBytes.java b/qpid/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/qpid/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<Fragment> fragments = new ArrayList<Fragment>(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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Sender.java b/qpid/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/qpid/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<Binary, OutcomeAction> _outcomeActions = Collections.synchronizedMap(new HashMap<Binary, OutcomeAction>());
+ 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<Binary, Outcome> 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<Binary, Outcome> 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<Binary, Outcome> 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<Section> 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<Binary, DeliveryState> 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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Session.java b/qpid/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/qpid/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<Receiver> _receivers = new ArrayList<Receiver>();
+ private List<Sender> _senders = new ArrayList<Sender>();
+ 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<Binary, Outcome> 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<Binary, Outcome> 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<Symbol, Filter> filters, Map<Binary, Outcome> 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<Binary, Outcome> 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<Binary, Outcome> 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<Symbol, Filter> filters, Map<Binary, Outcome> 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<Sender>(_senders))
+ {
+ sender.close();
+ }
+ for(Receiver receiver : new ArrayList<Receiver>(_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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Transaction.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/TransactionController.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-client/src/main/java/org/apache/qpid/amqp_1_0/client/Util.java b/qpid/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/qpid/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("<TYPE>=<VALUE>") + .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/qpid/java/amqp-1-0-common/build.xml b/qpid/java/amqp-1-0-common/build.xml new file mode 100644 index 0000000000..20b8b731b0 --- /dev/null +++ b/qpid/java/amqp-1-0-common/build.xml @@ -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. + - + --> +<project name="AMQP 1.0 Common" default="build"> + + <property name="module.genpom" value="true"/> + + <import file="../module.xml"/> + +</project> diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractDescribedTypeWriter.java b/qpid/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/qpid/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<V> implements ValueWriter<V>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractListWriter.java b/qpid/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/qpid/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<V> extends CompoundWriter<V>
+{
+ public AbstractListWriter(final Registry registry)
+ {
+ super(registry);
+ }
+
+ @Override
+ protected byte getFourOctetEncodingCode()
+ {
+ return (byte)0xd0;
+ }
+
+ @Override
+ protected byte getSingleOctetEncodingCode()
+ {
+ return (byte)0xc0;
+ }
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/AbstractMapWriter.java b/qpid/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/qpid/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<V> extends CompoundWriter<V>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayTypeConstructor.java b/qpid/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/qpid/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<Object[]>
+{
+
+
+
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ArrayWriter.java b/qpid/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/qpid/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<Object[]>
+{
+ 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<Object[]> FACTORY = new Factory<Object[]>()
+ {
+
+ public ValueWriter<Object[]> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryString.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BinaryWriter.java b/qpid/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/qpid/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<Binary>
+{
+ 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<Binary> FACTORY = new Factory<Binary>()
+ {
+
+ public ValueWriter<Binary> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanConstructor.java b/qpid/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/qpid/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<Boolean> TRUE_INSTANCE = new TypeConstructor<Boolean>() + { + public Boolean construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return Boolean.TRUE; + } + }; + + private static final TypeConstructor<Boolean> FALSE_INSTANCE = new TypeConstructor<Boolean>() + { + public Boolean construct(final ByteBuffer in, final ValueHandler handler) throws AmqpErrorException + { + return Boolean.FALSE; + } + }; + private static final TypeConstructor<Boolean> BYTE_INSTANCE = new TypeConstructor<Boolean>() + { + 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<Boolean> getTrueInstance() + { + return TRUE_INSTANCE; + } + + public static TypeConstructor<Boolean> getFalseInstance() + { + return FALSE_INSTANCE; + } + + public static TypeConstructor<Boolean> getByteInstance() + { + return BYTE_INSTANCE; + } +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/BooleanWriter.java b/qpid/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/qpid/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<Boolean>
+{
+ 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<Boolean> FACTORY = new Factory<Boolean>()
+ {
+
+ public ValueWriter<Boolean> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteArrayWriter.java b/qpid/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/qpid/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<byte[]>
+{
+
+ @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<byte[]> FACTORY = new Factory<byte[]>()
+ {
+
+ public ValueWriter<byte[]> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteBufferWriter.java b/qpid/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/qpid/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<ByteBuffer>
+{
+
+ @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<ByteBuffer> FACTORY = new Factory<ByteBuffer>()
+ {
+
+ public ValueWriter<ByteBuffer> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ByteWriter.java b/qpid/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/qpid/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<Byte>
+{
+ 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<Byte> FACTORY = new Factory<Byte>()
+ {
+
+ public ValueWriter<Byte> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CharWriter.java b/qpid/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/qpid/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<Character>
+{
+ 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<Character> FACTORY = new Factory<Character>()
+ {
+
+ public ValueWriter<Character> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeAssembler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/CompoundWriter.java b/qpid/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/qpid/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<V> implements ValueWriter<V>
+{
+ private int _length;
+ private Registry _registry;
+ private static final int LARGE_COMPOUND_THRESHOLD_COUNT = 25;
+ private ValueWriter _delegate;
+ private Map<Class, ValueWriter> _writerCache = new HashMap<Class, ValueWriter>();
+
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DecimalConstructor.java b/qpid/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/qpid/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<BigDecimal> +{ + + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DefaultDescribedTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DelegatingValueWriter.java b/qpid/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/qpid/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<V> implements ValueWriter<V>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedType.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructor.java b/qpid/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/qpid/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<T extends Object>
+{
+ public TypeConstructor<T> construct(final TypeConstructor describedConstructor) throws AmqpErrorException
+ {
+ return new TypeConstructor<T>()
+ {
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DescribedTypeConstructorRegistry.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/DoubleWriter.java b/qpid/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/qpid/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<Double>
+{
+ 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<Double> FACTORY = new Factory<Double>()
+ {
+
+ public ValueWriter<Double> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/Encoder.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedEightWriter.java b/qpid/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/qpid/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<T extends Object> implements ValueWriter<T>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedFourWriter.java b/qpid/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/qpid/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<T extends Object> implements ValueWriter<T>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedOneWriter.java b/qpid/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/qpid/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<T> implements ValueWriter<T> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedSixteenWriter.java b/qpid/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/qpid/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<T extends Object> implements ValueWriter<T>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FixedTwoWriter.java b/qpid/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/qpid/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 <T extends Object> implements ValueWriter<T>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FloatWriter.java b/qpid/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/qpid/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<Float>
+{
+ 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<Float> FACTORY = new Factory<Float>()
+ {
+
+ public ValueWriter<Float> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/FrameWriter.java b/qpid/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/qpid/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<AMQFrame>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/IntegerWriter.java b/qpid/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/qpid/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<Integer>
+{
+ private static final byte EIGHT_BYTE_FORMAT_CODE = (byte)0x71;
+ private static final byte ONE_BYTE_FORMAT_CODE = (byte) 0x54;
+
+ private ValueWriter<Integer> _delegate;
+
+ private final FixedFourWriter<Integer> _eightByteWriter = new FixedFourWriter<Integer>()
+ {
+
+ @Override
+ byte getFormatCode()
+ {
+ return EIGHT_BYTE_FORMAT_CODE;
+ }
+
+ @Override
+ int convertValueToInt(Integer value)
+ {
+ return value.intValue();
+ }
+ };
+
+ private final ValueWriter<Integer> _oneByteWriter = new FixedOneWriter<Integer>()
+ {
+
+ @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<Integer> FACTORY = new Factory<Integer>()
+ {
+
+ public ValueWriter<Integer> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ListWriter.java b/qpid/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/qpid/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<List>
+{
+ private static class NonEmptyListWriter extends AbstractListWriter<List>
+ {
+ 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<List> _emptyListWriter = new EmptyListValueWriter();
+
+
+ private ValueWriter<List> _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<List> FACTORY = new Factory<List>()
+ {
+
+ public ValueWriter<List> 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<List>
+ {
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/LongWriter.java b/qpid/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/qpid/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<Long>
+{
+ private static final byte EIGHT_BYTE_FORMAT_CODE = (byte) 0x81;
+
+
+ private static final byte ONE_BYTE_FORMAT_CODE = (byte) 0x55;
+
+ private ValueWriter<Long> _delegate;
+
+ private final FixedEightWriter<Long> _eightByteWriter = new FixedEightWriter<Long>()
+ {
+
+ @Override
+ byte getFormatCode()
+ {
+ return EIGHT_BYTE_FORMAT_CODE;
+ }
+
+ @Override
+ long convertValueToLong(Long value)
+ {
+ return value;
+ }
+
+ };
+
+ private final ValueWriter<Long> _oneByteWriter = new FixedOneWriter<Long>()
+ {
+
+ @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<Long> FACTORY = new Factory<Long>()
+ {
+
+ public ValueWriter<Long> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/MapWriter.java b/qpid/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/qpid/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<Map>
+{
+ private Map _map;
+ private Object _value;
+ private Iterator<Map.Entry> _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<Map> FACTORY = new Factory<Map>()
+ {
+
+ public ValueWriter<Map> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullTypeConstructor.java b/qpid/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/qpid/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<Void> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/NullWriter.java b/qpid/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/qpid/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<Void>
+{
+ 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<Void> FACTORY = new Factory<Void>()
+ {
+
+ public ValueWriter<Void> newInstance(Registry registry)
+ {
+ return new NullWriter();
+ }
+ };
+
+ public static void register(ValueWriter.Registry registry)
+ {
+ registry.register(Void.TYPE, FACTORY);
+ }
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ProtocolHeaderHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/RestrictedTypeValueWriter.java b/qpid/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/qpid/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<V> extends DelegatingValueWriter<RestrictedType<V>>
+{
+ public RestrictedTypeValueWriter(final Registry registry)
+ {
+ super(registry);
+ }
+
+ @Override
+ protected Object getUnderlyingValue(final RestrictedType<V> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ShortWriter.java b/qpid/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/qpid/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<Short>
+{
+
+ 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<Short> FACTORY = new Factory<Short>()
+ {
+
+ public ValueWriter<Short> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SimpleVariableWidthWriter.java b/qpid/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/qpid/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<V> extends VariableWidthWriter<V>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallIntConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallLongConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallUIntConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SmallULongConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringTypeConstructor.java b/qpid/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/qpid/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<BinaryString, String> _cachedValues = new ValueCache<BinaryString, String>(10);
+
+ private static final class ValueCache<K,V> extends LinkedHashMap<K,V>
+ {
+ private final int _cacheSize;
+
+ public ValueCache(int cacheSize)
+ {
+ _cacheSize = cacheSize;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<K, V> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/StringWriter.java b/qpid/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/qpid/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<String>
+{
+ 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<K,V> extends LinkedHashMap<K,V>
+ {
+ private final int _cacheSize;
+
+ public ValueCache(int cacheSize)
+ {
+ _cacheSize = cacheSize;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry<K, V> eldest)
+ {
+ return size() > _cacheSize;
+ }
+
+ public boolean isFull()
+ {
+ return size() == _cacheSize;
+ }
+ }
+
+ private final ValueCache<String, byte[]> _cachedEncodings = new ValueCache<String, byte[]>(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<String> FACTORY = new Factory<String>()
+ {
+
+ public ValueWriter<String> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolArrayWriter.java b/qpid/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/qpid/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<Symbol[]> +{ + + 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<Symbol[]> FACTORY = new Factory<Symbol[]>() + { + + public ValueWriter<Symbol[]> newInstance(Registry registry) + { + return new SymbolArrayWriter(); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Symbol[].class, FACTORY); + } +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolTypeConstructor.java b/qpid/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/qpid/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<BinaryString, Symbol> SYMBOL_MAP =
+ new ConcurrentHashMap<BinaryString, Symbol>(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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/SymbolWriter.java b/qpid/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/qpid/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<Symbol>
+{
+ 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<Symbol> FACTORY = new Factory<Symbol>()
+ {
+
+ public ValueWriter<Symbol> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TimestampWriter.java b/qpid/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/qpid/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<Date>
+{
+ 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<Date> FACTORY = new Factory<Date>()
+ {
+
+ public ValueWriter<Date> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/TypeConstructor.java b/qpid/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/qpid/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<T>
+{
+
+ public T construct(final ByteBuffer in, ValueHandler handler) throws AmqpErrorException;
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UByteTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UIntTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ULongTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UShortTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UUIDWriter.java b/qpid/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/qpid/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<UUID>
+{
+ 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<UUID> FACTORY = new Factory<UUID>()
+ {
+
+ public ValueWriter<UUID> newInstance(Registry registry)
+ {
+ return new UUIDWriter();
+ }
+ };
+
+ public static void register(ValueWriter.Registry registry)
+ {
+ registry.register(UUID.class, FACTORY);
+ }
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedByteWriter.java b/qpid/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/qpid/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<UnsignedByte>
+{
+ 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<UnsignedByte> FACTORY = new Factory<UnsignedByte>()
+ {
+
+ public ValueWriter<UnsignedByte> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedIntegerWriter.java b/qpid/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/qpid/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<UnsignedInteger>
+{
+ 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<UnsignedInteger> _delegate;
+
+ private final FixedFourWriter<UnsignedInteger> _eightByteWriter = new FixedFourWriter<UnsignedInteger>()
+ {
+
+ @Override
+ byte getFormatCode()
+ {
+ return EIGHT_BYTE_FORMAT_CODE;
+ }
+
+ @Override
+ int convertValueToInt(UnsignedInteger value)
+ {
+ return value.intValue();
+ }
+ };
+
+ private final ValueWriter<UnsignedInteger> _oneByteWriter = new FixedOneWriter<UnsignedInteger>()
+ {
+
+ @Override protected byte getFormatCode()
+ {
+ return ONE_BYTE_FORMAT_CODE;
+ }
+
+ @Override protected byte convertToByte(final UnsignedInteger value)
+ {
+ return value.byteValue();
+ }
+ };
+
+ private final ValueWriter<UnsignedInteger> _zeroByteWriter = new ValueWriter<UnsignedInteger>()
+ {
+ 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<UnsignedInteger> FACTORY = new Factory<UnsignedInteger>()
+ {
+
+ public ValueWriter<UnsignedInteger> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedLongWriter.java b/qpid/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/qpid/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<UnsignedLong>
+{
+
+
+ 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<UnsignedLong> _delegate;
+
+ private final FixedEightWriter<UnsignedLong> _eightByteWriter = new FixedEightWriter<UnsignedLong>()
+ {
+
+ @Override
+ byte getFormatCode()
+ {
+ return EIGHT_BYTE_FORMAT_CODE;
+ }
+
+ @Override
+ long convertValueToLong(UnsignedLong value)
+ {
+ return value.longValue();
+ }
+
+ };
+
+ private final ValueWriter<UnsignedLong> _oneByteWriter = new FixedOneWriter<UnsignedLong>()
+ {
+
+ @Override protected byte getFormatCode()
+ {
+ return ONE_BYTE_FORMAT_CODE;
+ }
+
+ @Override protected byte convertToByte(final UnsignedLong value)
+ {
+ return value.byteValue();
+ }
+ };
+
+ private final ValueWriter<UnsignedLong> _zeroByteWriter = new ValueWriter<UnsignedLong>()
+ {
+ 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<UnsignedLong> FACTORY = new Factory<UnsignedLong>()
+ {
+
+ public ValueWriter<UnsignedLong> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/UnsignedShortWriter.java b/qpid/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/qpid/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<UnsignedShort>
+{
+ 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<UnsignedShort> FACTORY = new Factory<UnsignedShort>()
+ {
+
+ public ValueWriter<UnsignedShort> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueProducingProtocolHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ValueWriter.java b/qpid/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/qpid/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<T extends Object>
+{
+
+
+
+ public static interface Factory<V extends Object>
+ {
+ ValueWriter<V> newInstance(Registry registry);
+ }
+
+ public static interface Registry
+ {
+ public static interface Source
+ {
+ public Registry getDescribedTypeRegistry();
+ }
+
+ <V extends Object> ValueWriter<V> getValueWriter(V value);
+ <V extends Object> ValueWriter<V> getValueWriter(V value, Map<Class, ValueWriter> localCache);
+ <V extends Object> ValueWriter<V> register(Class<V> clazz, ValueWriter.Factory<V> writer);
+
+ }
+
+
+ int writeToBuffer(ByteBuffer buffer);
+
+ void setValue(T frameBody);
+
+ boolean isComplete();
+
+ boolean isCacheable();
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthTypeConstructor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/VariableWidthWriter.java b/qpid/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/qpid/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<V> implements ValueWriter<V>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/WrapperTypeValueWriter.java b/qpid/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/qpid/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<WrapperType>
+{
+ 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<? extends WrapperType> clazz)
+ {
+ registry.register(clazz, FACTORY);
+ }}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroListConstructor.java b/qpid/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/qpid/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<List> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroUIntConstructor.java b/qpid/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/qpid/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<UnsignedInteger> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/codec/ZeroULongConstructor.java b/qpid/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/qpid/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<UnsignedLong> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQFrame.java b/qpid/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/qpid/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<T>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/AMQPProtocolHeaderHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/ConnectionHandler.java b/qpid/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/qpid/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<T> implements FrameOutputHandler<T>, FrameSource
+ {
+
+ private static final ByteBuffer EMPTY_BYTEBUFFER = ByteBuffer.wrap(new byte[0]);
+ private final BlockingQueue<AMQFrame<T>> _queue = new ArrayBlockingQueue<AMQFrame<T>>(100);
+ private ConnectionEndpoint _conn;
+
+ private final AMQFrame<T> _endOfFrameMarker = new AMQFrame<T>(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<T> frame)
+ {
+ send(frame, null);
+ }
+
+ public void send(final AMQFrame<T> 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<T> 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<T>
+ {
+ AMQFrame<T> 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<BytesSource> _sources = new LinkedList<BytesSource>();
+
+ 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<Open> writer = registry.getValueWriter(open);
+
+ System.out.println("------ Encode (time in ms for 1 million opens)");
+ Long myLong = Long.valueOf(32);
+ ValueWriter<Long> writer2 = registry.getValueWriter(myLong);
+ Double myDouble = Double.valueOf(3.14159265359);
+ ValueWriter<Double> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameParsingError.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/FrameTypeHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/OversizeFrameException.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrame.java b/qpid/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/qpid/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<SaslFrameBody>
+{
+
+ public SASLFrame(SaslFrameBody frameBody)
+ {
+ super(frameBody);
+ }
+
+ @Override public short getChannel()
+ {
+ return (short)0;
+ }
+
+ @Override public byte getFrameType()
+ {
+ return (byte)1;
+ }
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLFrameHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/SASLProtocolHeaderHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/framing/TransportFrame.java b/qpid/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/qpid/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<FrameBody> +{ + + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/MessageAttributes.java b/qpid/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/qpid/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<Symbol, Object>
+{
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoder.java b/qpid/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/qpid/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<Section> parseAll(ByteBuffer buf) throws AmqpErrorException;
+ public Section readSection(ByteBuffer buf) throws AmqpErrorException;
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionDecoderImpl.java b/qpid/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/qpid/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<Section> parseAll(ByteBuffer buf) throws AmqpErrorException
+ {
+
+ List<Section> obj = new ArrayList<Section>();
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoder.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/messaging/SectionEncoderImpl.java b/qpid/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/qpid/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<byte[]> _output = new ArrayList<byte[]>();
+ 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<Object> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPFrameTransport.java b/qpid/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/qpid/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<AMQFrame<FrameBody>>, FrameOutputHandler<FrameBody> +{ + 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<AMQFrame<FrameBody>> _queue = new ArrayBlockingQueue<AMQFrame<FrameBody>>(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<FrameBody> frame) + { + frame.getFrameBody().invoke(frame.getChannel(), _endpoint); + } + + + public boolean canSend() + { + return _queue.remainingCapacity() != 0; + } + + public void send(AMQFrame<FrameBody> frame) + { + send(frame, null); + } + + + public void send(final AMQFrame<FrameBody> 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<FrameBody> getNextFrame() + { + synchronized(_endpoint.getLock()) + { + AMQFrame<FrameBody> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/AMQPTransport.java b/qpid/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/qpid/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<FrameBody> _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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesProcessor.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/BytesTransport.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CallbackHandlerSource.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/CircularBytesBuffer.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEndpoint.java b/qpid/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/qpid/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<FrameBody> _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<SaslFrameBody> _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<FrameBody> 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<FrameBody> 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<SaslFrameBody> saslFrameOutput)
+ {
+ _saslFrameOutput = saslFrameOutput;
+ }
+
+ public void setOnSaslComplete(Runnable task)
+ {
+ _onSaslCompleteTask = task;
+
+ }
+
+ public boolean isAuthenticated()
+ {
+ return _authenticated;
+ }
+
+ public void initiateSASL()
+ {
+ SaslMechanisms mechanisms = new SaslMechanisms();
+ final Enumeration<SaslServerFactory> saslServerFactories = Sasl.getSaslServerFactories();
+
+ SaslServerFactory f;
+ ArrayList<Symbol> mechanismsList = new ArrayList<Symbol>();
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionEventListener.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ConnectionState.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java new file mode 100644 index 0000000000..1fa5df4640 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Container.java @@ -0,0 +1,76 @@ +/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either 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;
+
+public class Container
+{
+
+ 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 + ')';
+
+ }
+
+
+ public Container(String id)
+ {
+ _id = id;
+ }
+
+ public String getId()
+ {
+ return _id;
+ }
+
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Delivery.java b/qpid/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/qpid/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<Transfer> _transfers = new ArrayList<Transfer>(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<Transfer> getTransfers() + { + return _transfers; + } + + public UnsignedInteger getDeliveryId() + { + return _deliveryId; + } + + public LinkEndpoint getLinkEndpoint() + { + return _linkEndpoint; + } + + public Binary getDeliveryTag() + { + return _deliveryTag; + } +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/DeliveryStateHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ErrorHandler.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameOutputHandler.java b/qpid/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/qpid/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<T>
+{
+ boolean canSend();
+
+ void send(AMQFrame<T> frame);
+ void send(AMQFrame<T> frame, ByteBuffer payload);
+
+ void close();
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/FrameTransport.java b/qpid/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/qpid/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<T extends AMQFrame> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEndpoint.java b/qpid/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/qpid/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<T extends LinkEventListener>
+{
+
+ 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<Binary,Delivery> _unsettledTransfers = new HashMap<Binary,Delivery>();
+
+ LinkEndpoint(final SessionEndpoint sessionEndpoint, String name, Map<Binary, Outcome> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/LinkEventListener.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/Node.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ProtocolHeaderTransport.java b/qpid/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/qpid/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<Binary,BytesTransport> _headersMap; + + private BytesTransport _delegate; + private ByteBuffer _bytesToSend; + + private byte[] _header = new byte[8]; + private int _received; + private ByteBuffer _outputBuffer; + + public ProtocolHeaderTransport(Map<Binary, BytesTransport> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkEndpoint.java b/qpid/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/qpid/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<ReceivingLinkListener>
+{
+
+
+ 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<Binary, Object> _unsettledMap = new LinkedHashMap<Binary, Object>();
+ private Map<Binary, TransientState> _unsettledIds = new LinkedHashMap<Binary, TransientState>();
+ 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<Binary, Outcome> 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<UnsignedInteger, UnsignedInteger> ranges = new TreeMap<UnsignedInteger,UnsignedInteger>();
+
+ synchronized(getLock())
+ {
+
+ Iterator<Binary> iter = _unsettledIds.keySet().iterator();
+ List<Binary> tagsToUpdate = new ArrayList<Binary>();
+ 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<UnsignedInteger,UnsignedInteger> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingLinkListener.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/ReceivingSessionHalfEndpoint.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpoint.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLEndpointImpl.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLFrameTransport.java b/qpid/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/qpid/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<SASLFrame> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SASLTransport.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkEndpoint.java b/qpid/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/qpid/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<SendingLinkListener>
+{
+
+ private UnsignedInteger _lastDeliveryId;
+ private Binary _lastDeliveryTag;
+ private Map<Binary, UnsignedInteger> _unsettledMap = new HashMap<Binary, UnsignedInteger>();
+ private Binary _transactionId;
+
+ public SendingLinkEndpoint(final SessionEndpoint sessionEndpoint, String name)
+ {
+ this(sessionEndpoint, name, null);
+ }
+
+ public SendingLinkEndpoint(final SessionEndpoint sessionEndpoint, String name, Map<Binary, Outcome> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingLinkListener.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SendingSessionHalfEndpoint.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SequenceNumber.java b/qpid/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/qpid/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<SequenceNumber>, 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionAttachment.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEndpoint.java b/qpid/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/qpid/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<String, LinkEndpoint> _linkMap = new HashMap<String, LinkEndpoint>();
+ private final Map<LinkEndpoint, UnsignedInteger> _localLinkEndpoints = new HashMap<LinkEndpoint, UnsignedInteger>();
+ private final Map<UnsignedInteger, LinkEndpoint> _remoteLinkEndpoints = new HashMap<UnsignedInteger, LinkEndpoint>();
+
+ private long _timeout;
+
+
+ private ConnectionEndpoint _connection;
+ private long _lastAttachedTime;
+
+ private short _receivingChannel;
+ private short _sendingChannel;
+
+ private LinkedHashMap<UnsignedInteger,Delivery> _outgoingUnsettled;
+ private LinkedHashMap<UnsignedInteger,Delivery> _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<UnsignedInteger,Delivery>(DEFAULT_SESSION_BUFFER_SIZE);
+ _incomingUnsettled = new LinkedHashMap<UnsignedInteger, Delivery>(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<UnsignedInteger> handles = new ArrayList<UnsignedInteger>(_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<UnsignedInteger, Delivery> 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<Binary, Outcome> unsettled)
+ {
+ return createSendingLinkEndpoint(name, targetAddr, sourceAddr, false, unsettled);
+ }
+
+ public SendingLinkEndpoint createSendingLinkEndpoint(final String name, final String targetAddr,
+ final String sourceAddr, boolean durable,
+ Map<Binary, Outcome> 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<Binary, Outcome> 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<String, LinkEndpoint> getLinkMap()
+ {
+ return _linkMap;
+ }
+
+
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionEventListener.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionHalfEndpoint.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/SessionState.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/StateChangeListener.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/transport/UnsettledTransfer.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/AmqpErrorException.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Binary.java b/qpid/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/qpid/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<Binary> 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DeliveryState.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/DistributionMode.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/ErrorCondition.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/FrameBody.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/GlobalTxId.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/LifetimePolicy.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Outcome.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/RestrictedType.java b/qpid/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/qpid/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>
+{
+ V getValue();
+}
diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/SaslFrameBody.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Section.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Source.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Symbol.java b/qpid/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/qpid/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<Symbol>, CharSequence
+{
+ private final String _underlying;
+ private static final ConcurrentHashMap<String, Symbol> _symbols = new ConcurrentHashMap<String, Symbol>(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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/Target.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnCapability.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/TxnId.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedByte.java b/qpid/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/qpid/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<UnsignedByte>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedInteger.java b/qpid/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/qpid/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<UnsignedInteger>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedLong.java b/qpid/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/qpid/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<UnsignedLong>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/UnsignedShort.java b/qpid/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/qpid/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<UnsignedShort>
+{
+ 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/WrapperType.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/codec/AMQPDescribedTypeRegistry.java b/qpid/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/qpid/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<Object, DescribedTypeConstructor> _constructorRegistry = new HashMap<Object, DescribedTypeConstructor>(); + + 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<Class, ValueWriter.Factory> _writerMap = new HashMap<Class, ValueWriter.Factory>(); + private final Map<Class, ValueWriter> _cachedWriters = new HashMap<Class,ValueWriter>(); + + public <V extends Object> ValueWriter<V> getValueWriter(V value, Map<Class, ValueWriter> localCache) + { + Class<? extends Object> 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 <V extends Object> ValueWriter<V> getValueWriter(V value) + { + + Class<? extends Object> clazz = value == null ? Void.TYPE : value.getClass(); + + ValueWriter writer = null; // TODO _cachedWriters.get(clazz); + if(writer == null || !writer.isComplete()) + { + ValueWriter.Factory<V> factory = (ValueWriter.Factory<V>) (_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<V>) 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 <V extends Object> ValueWriter<V> register(Class<V> clazz, ValueWriter.Factory<V> writer) + { + return (ValueWriter<V>) _writerMap.put(clazz, writer); + } + +} + +
\ No newline at end of file diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Accepted.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpSequence.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/AmqpValue.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ApplicationProperties.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Data.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnClose.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinks.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoLinksOrMessages.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeleteOnNoMessages.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/DeliveryAnnotations.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/ExactSubjectFilter.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Filter.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Footer.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Header.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/JMSSelectorFilter.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MatchingSubjectFilter.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/MessageAnnotations.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Modified.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/NoLocalFilter.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Properties.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Received.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Rejected.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Released.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Source.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/StdDistMode.java b/qpid/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/qpid/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<Symbol> + + { + + + + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/Target.java b/qpid/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/qpid/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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusDurability.java b/qpid/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/qpid/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<UnsignedInteger> + + { + + + + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/TerminusExpiryPolicy.java b/qpid/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/qpid/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<Symbol> + + { + + + + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedConstructor.java b/qpid/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/qpid/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<Accepted> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AcceptedWriter.java b/qpid/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/qpid/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<Accepted> +{ + 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<Accepted> + { + 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<Accepted> FACTORY = new Factory<Accepted>() + { + + public ValueWriter<Accepted> newInstance(Registry registry) + { + return new AcceptedWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Accepted.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceConstructor.java b/qpid/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/qpid/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<AmqpSequence> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpSequenceWriter.java b/qpid/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/qpid/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<AmqpSequence> +{ + 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<AmqpSequence> FACTORY = new Factory<AmqpSequence>() + { + + public ValueWriter<AmqpSequence> newInstance(Registry registry) + { + return new AmqpSequenceWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(AmqpSequence.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueConstructor.java b/qpid/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/qpid/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<AmqpValue> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/AmqpValueWriter.java b/qpid/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/qpid/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<AmqpValue> +{ + 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<AmqpValue> FACTORY = new Factory<AmqpValue>() + { + + public ValueWriter<AmqpValue> newInstance(Registry registry) + { + return new AmqpValueWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(AmqpValue.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesConstructor.java b/qpid/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/qpid/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<ApplicationProperties> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ApplicationPropertiesWriter.java b/qpid/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/qpid/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<ApplicationProperties> +{ + 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<ApplicationProperties> FACTORY = new Factory<ApplicationProperties>() + { + + public ValueWriter<ApplicationProperties> newInstance(Registry registry) + { + return new ApplicationPropertiesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(ApplicationProperties.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataConstructor.java b/qpid/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/qpid/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<Data> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DataWriter.java b/qpid/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/qpid/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<Data> +{ + 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<Data> FACTORY = new Factory<Data>() + { + + public ValueWriter<Data> newInstance(Registry registry) + { + return new DataWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Data.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseConstructor.java b/qpid/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/qpid/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<DeleteOnClose> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnCloseWriter.java b/qpid/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/qpid/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<DeleteOnClose> +{ + 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<DeleteOnClose> + { + 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<DeleteOnClose> FACTORY = new Factory<DeleteOnClose>() + { + + public ValueWriter<DeleteOnClose> newInstance(Registry registry) + { + return new DeleteOnCloseWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnClose.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksConstructor.java b/qpid/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/qpid/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<DeleteOnNoLinks> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesConstructor.java b/qpid/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/qpid/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<DeleteOnNoLinksOrMessages> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksOrMessagesWriter.java b/qpid/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/qpid/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<DeleteOnNoLinksOrMessages> +{ + 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<DeleteOnNoLinksOrMessages> + { + 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<DeleteOnNoLinksOrMessages> FACTORY = new Factory<DeleteOnNoLinksOrMessages>() + { + + public ValueWriter<DeleteOnNoLinksOrMessages> newInstance(Registry registry) + { + return new DeleteOnNoLinksOrMessagesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnNoLinksOrMessages.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoLinksWriter.java b/qpid/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/qpid/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<DeleteOnNoLinks> +{ + 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<DeleteOnNoLinks> + { + 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<DeleteOnNoLinks> FACTORY = new Factory<DeleteOnNoLinks>() + { + + public ValueWriter<DeleteOnNoLinks> newInstance(Registry registry) + { + return new DeleteOnNoLinksWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnNoLinks.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesConstructor.java b/qpid/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/qpid/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<DeleteOnNoMessages> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeleteOnNoMessagesWriter.java b/qpid/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/qpid/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<DeleteOnNoMessages> +{ + 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<DeleteOnNoMessages> + { + 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<DeleteOnNoMessages> FACTORY = new Factory<DeleteOnNoMessages>() + { + + public ValueWriter<DeleteOnNoMessages> newInstance(Registry registry) + { + return new DeleteOnNoMessagesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeleteOnNoMessages.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsConstructor.java b/qpid/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/qpid/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<DeliveryAnnotations> +{ + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/DeliveryAnnotationsWriter.java b/qpid/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/qpid/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<DeliveryAnnotations> +{ + 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<DeliveryAnnotations> FACTORY = new Factory<DeliveryAnnotations>() + { + + public ValueWriter<DeliveryAnnotations> newInstance(Registry registry) + { + return new DeliveryAnnotationsWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(DeliveryAnnotations.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterConstructor.java b/qpid/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..48bec31797 --- /dev/null +++ b/qpid/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<ExactSubjectFilter> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:exact-subject-filter:string"), + }; + + 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/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterWriter.java b/qpid/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..75e2df4b65 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ExactSubjectFilterWriter.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.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.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.ExactSubjectFilter; + +public class ExactSubjectFilterWriter extends AbstractDescribedTypeWriter<ExactSubjectFilter> +{ + 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 Symbol.valueOf("amqp:exact-subject-filter:string"); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory<ExactSubjectFilter> FACTORY = new Factory<ExactSubjectFilter>() + { + + public ValueWriter<ExactSubjectFilter> newInstance(Registry registry) + { + return new ExactSubjectFilterWriter(registry); + } + }; + + public static void register(Registry registry) + { + registry.register(ExactSubjectFilter.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterConstructor.java b/qpid/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/qpid/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<Footer> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:footer:map"),UnsignedLong.valueOf(0x0000000000000078L), + }; + + private static final FooterConstructor INSTANCE = new FooterConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public Footer construct(Object underlying) + { + + if(underlying instanceof Map) + { + return new Footer((Map)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterWriter.java new file mode 100644 index 0000000000..3ffde7c663 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/FooterWriter.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.Footer; + +public class FooterWriter extends AbstractDescribedTypeWriter<Footer> +{ + private Footer _value; + + + + public FooterWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Footer value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000078L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory<Footer> FACTORY = new Factory<Footer>() + { + + public ValueWriter<Footer> newInstance(Registry registry) + { + return new FooterWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Footer.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderConstructor.java new file mode 100644 index 0000000000..5a1b4ceb1b --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderConstructor.java @@ -0,0 +1,207 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Header; + + +import java.util.List; + +public class HeaderConstructor extends DescribedTypeConstructor<Header> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:header:list"),UnsignedLong.valueOf(0x0000000000000070L), + }; + + private static final HeaderConstructor INSTANCE = new HeaderConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Header construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Header obj = new Header(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDurable( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setPriority( (UnsignedByte) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTtl( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setFirstAcquirer( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDeliveryCount( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderWriter.java new file mode 100644 index 0000000000..20605293e1 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/HeaderWriter.java @@ -0,0 +1,182 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Header; + +public class HeaderWriter extends AbstractDescribedTypeWriter<Header> +{ + private Header _value; + private int _count = -1; + + public HeaderWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Header value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getDeliveryCount() != null) + { + return 5; + } + + if( _value.getFirstAcquirer() != null) + { + return 4; + } + + if( _value.getTtl() != null) + { + return 3; + } + + if( _value.getPriority() != null) + { + return 2; + } + + if( _value.getDurable() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000070L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Header> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Header value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getDurable(); + + case 1: + return _value.getPriority(); + + case 2: + return _value.getTtl(); + + case 3: + return _value.getFirstAcquirer(); + + case 4: + return _value.getDeliveryCount(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Header> FACTORY = new Factory<Header>() + { + + public ValueWriter<Header> newInstance(Registry registry) + { + return new HeaderWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Header.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterConstructor.java new file mode 100644 index 0000000000..e222c3371e --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterConstructor.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.JMSSelectorFilter; + +public class JMSSelectorFilterConstructor extends DescribedTypeConstructor<JMSSelectorFilter> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:jms-selector-filter:string"), + }; + + private static final JMSSelectorFilterConstructor INSTANCE = new JMSSelectorFilterConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public JMSSelectorFilter construct(Object underlying) + { + + if(underlying instanceof String) + { + return new JMSSelectorFilter((String)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterWriter.java new file mode 100644 index 0000000000..4e2b9f8d24 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/JMSSelectorFilterWriter.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.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter; +import org.apache.qpid.amqp_1_0.type.messaging.MatchingSubjectFilter; + +public class JMSSelectorFilterWriter extends AbstractDescribedTypeWriter<JMSSelectorFilter> +{ + private JMSSelectorFilter _value; + + + + public JMSSelectorFilterWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final JMSSelectorFilter value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return Symbol.valueOf("amqp:jms-selector-filter:string"); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory<JMSSelectorFilter> FACTORY = new Factory<JMSSelectorFilter>() + { + + public ValueWriter<JMSSelectorFilter> newInstance(Registry registry) + { + return new JMSSelectorFilterWriter(registry); + } + }; + + public static void register(Registry registry) + { + registry.register(JMSSelectorFilter.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterConstructor.java new file mode 100644 index 0000000000..d9cdc7bbb9 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterConstructor.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.MatchingSubjectFilter; + +public class MatchingSubjectFilterConstructor extends DescribedTypeConstructor<MatchingSubjectFilter> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:matching-subject-filter:string"), + }; + + private static final MatchingSubjectFilterConstructor INSTANCE = new MatchingSubjectFilterConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public MatchingSubjectFilter construct(Object underlying) + { + + if(underlying instanceof String) + { + return new MatchingSubjectFilter((String)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterWriter.java new file mode 100644 index 0000000000..29fd304831 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MatchingSubjectFilterWriter.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.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.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.MatchingSubjectFilter; + +public class MatchingSubjectFilterWriter extends AbstractDescribedTypeWriter<MatchingSubjectFilter> +{ + private MatchingSubjectFilter _value; + + + + public MatchingSubjectFilterWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final MatchingSubjectFilter value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return Symbol.valueOf("amqp:matching-subject-filter:string"); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory<MatchingSubjectFilter> FACTORY = new Factory<MatchingSubjectFilter>() + { + + public ValueWriter<MatchingSubjectFilter> newInstance(Registry registry) + { + return new MatchingSubjectFilterWriter(registry); + } + }; + + public static void register(Registry registry) + { + registry.register(MatchingSubjectFilter.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsConstructor.java new file mode 100644 index 0000000000..b2f2ec5739 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsConstructor.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.MessageAnnotations; + + +import java.util.Map; + +public class MessageAnnotationsConstructor extends DescribedTypeConstructor<MessageAnnotations> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:message-annotations:map"),UnsignedLong.valueOf(0x0000000000000072L), + }; + + private static final MessageAnnotationsConstructor INSTANCE = new MessageAnnotationsConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public MessageAnnotations construct(Object underlying) + { + + if(underlying instanceof Map) + { + return new MessageAnnotations((Map)underlying); + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsWriter.java new file mode 100644 index 0000000000..400449c381 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/MessageAnnotationsWriter.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.MessageAnnotations; + +public class MessageAnnotationsWriter extends AbstractDescribedTypeWriter<MessageAnnotations> +{ + private MessageAnnotations _value; + + + + public MessageAnnotationsWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final MessageAnnotations value) + { + _value = value; + } + + @Override + protected void clear() + { + _value = null; + } + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000072L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return getRegistry().getValueWriter(_value.getValue()); + } + + private static Factory<MessageAnnotations> FACTORY = new Factory<MessageAnnotations>() + { + + public ValueWriter<MessageAnnotations> newInstance(Registry registry) + { + return new MessageAnnotationsWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(MessageAnnotations.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedConstructor.java new file mode 100644 index 0000000000..fb78708d7d --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedConstructor.java @@ -0,0 +1,154 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.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.Modified; + + +import java.util.List; +import java.util.Map; + +public class ModifiedConstructor extends DescribedTypeConstructor<Modified> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:modified:list"),UnsignedLong.valueOf(0x0000000000000027L), + }; + + private static final ModifiedConstructor INSTANCE = new ModifiedConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Modified construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Modified obj = new Modified(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDeliveryFailed( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setUndeliverableHere( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMessageAnnotations( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedWriter.java new file mode 100644 index 0000000000..df3063ee52 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ModifiedWriter.java @@ -0,0 +1,166 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Modified; + +public class ModifiedWriter extends AbstractDescribedTypeWriter<Modified> +{ + private Modified _value; + private int _count = -1; + + public ModifiedWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Modified value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getMessageAnnotations() != null) + { + return 3; + } + + if( _value.getUndeliverableHere() != null) + { + return 2; + } + + if( _value.getDeliveryFailed() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000027L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Modified> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Modified value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getDeliveryFailed(); + + case 1: + return _value.getUndeliverableHere(); + + case 2: + return _value.getMessageAnnotations(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Modified> FACTORY = new Factory<Modified>() + { + + public ValueWriter<Modified> newInstance(Registry registry) + { + return new ModifiedWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Modified.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterConstructor.java new file mode 100644 index 0000000000..2bcf44e6d5 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterConstructor.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.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.JMSSelectorFilter; +import org.apache.qpid.amqp_1_0.type.messaging.NoLocalFilter; + +public class NoLocalFilterConstructor extends DescribedTypeConstructor<NoLocalFilter> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:no-local-filter:list"), + }; + + private static final NoLocalFilterConstructor INSTANCE = new NoLocalFilterConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + + public NoLocalFilter construct(Object underlying) + { + return NoLocalFilter.INSTANCE; + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterWriter.java new file mode 100644 index 0000000000..1e7dce7600 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/NoLocalFilterWriter.java @@ -0,0 +1,89 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.ListWriter; +import org.apache.qpid.amqp_1_0.codec.ValueWriter; +import org.apache.qpid.amqp_1_0.type.Symbol; +import org.apache.qpid.amqp_1_0.type.messaging.NoLocalFilter; + +public class NoLocalFilterWriter extends AbstractDescribedTypeWriter<NoLocalFilter> +{ + private NoLocalFilter _value; + private int _count = -1; + + public NoLocalFilterWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final NoLocalFilter value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return Symbol.valueOf("amqp:no-local-filter:list"); + } + + @Override + protected ValueWriter createDescribedWriter() + { + return new ListWriter.EmptyListValueWriter(); + } + + private static Factory<NoLocalFilter> FACTORY = new Factory<NoLocalFilter>() + { + + public ValueWriter<NoLocalFilter> newInstance(Registry registry) + { + return new NoLocalFilterWriter(registry); + } + }; + + public static void register(Registry registry) + { + registry.register(NoLocalFilter.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesConstructor.java new file mode 100644 index 0000000000..98b911f341 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesConstructor.java @@ -0,0 +1,424 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Properties; + + +import java.util.List; +import java.util.Date; + +public class PropertiesConstructor extends DescribedTypeConstructor<Properties> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:properties:list"),UnsignedLong.valueOf(0x0000000000000073L), + }; + + private static final PropertiesConstructor INSTANCE = new PropertiesConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Properties construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Properties obj = new Properties(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMessageId( val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setUserId( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTo( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSubject( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setReplyTo( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setCorrelationId( val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setContentType( (Symbol) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setContentEncoding( (Symbol) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setAbsoluteExpiryTime( (Date) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setCreationTime( (Date) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setGroupId( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setGroupSequence( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setReplyToGroupId( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesWriter.java new file mode 100644 index 0000000000..021338bcfa --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/PropertiesWriter.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.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.Properties; + +public class PropertiesWriter extends AbstractDescribedTypeWriter<Properties> +{ + private Properties _value; + private int _count = -1; + + public PropertiesWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Properties value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getReplyToGroupId() != null) + { + return 13; + } + + if( _value.getGroupSequence() != null) + { + return 12; + } + + if( _value.getGroupId() != null) + { + return 11; + } + + if( _value.getCreationTime() != null) + { + return 10; + } + + if( _value.getAbsoluteExpiryTime() != null) + { + return 9; + } + + if( _value.getContentEncoding() != null) + { + return 8; + } + + if( _value.getContentType() != null) + { + return 7; + } + + if( _value.getCorrelationId() != null) + { + return 6; + } + + if( _value.getReplyTo() != null) + { + return 5; + } + + if( _value.getSubject() != null) + { + return 4; + } + + if( _value.getTo() != null) + { + return 3; + } + + if( _value.getUserId() != null) + { + return 2; + } + + if( _value.getMessageId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000073L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Properties> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Properties value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getMessageId(); + + case 1: + return _value.getUserId(); + + case 2: + return _value.getTo(); + + case 3: + return _value.getSubject(); + + case 4: + return _value.getReplyTo(); + + case 5: + return _value.getCorrelationId(); + + case 6: + return _value.getContentType(); + + case 7: + return _value.getContentEncoding(); + + case 8: + return _value.getAbsoluteExpiryTime(); + + case 9: + return _value.getCreationTime(); + + case 10: + return _value.getGroupId(); + + case 11: + return _value.getGroupSequence(); + + case 12: + return _value.getReplyToGroupId(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Properties> FACTORY = new Factory<Properties>() + { + + public ValueWriter<Properties> newInstance(Registry registry) + { + return new PropertiesWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Properties.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedConstructor.java new file mode 100644 index 0000000000..a515379d33 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedConstructor.java @@ -0,0 +1,126 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Received; + + +import java.util.List; + +public class ReceivedConstructor extends DescribedTypeConstructor<Received> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:received:list"),UnsignedLong.valueOf(0x0000000000000023L), + }; + + private static final ReceivedConstructor INSTANCE = new ReceivedConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Received construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Received obj = new Received(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSectionNumber( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSectionOffset( (UnsignedLong) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedWriter.java new file mode 100644 index 0000000000..76af939db5 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReceivedWriter.java @@ -0,0 +1,158 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Received; + +public class ReceivedWriter extends AbstractDescribedTypeWriter<Received> +{ + private Received _value; + private int _count = -1; + + public ReceivedWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Received value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getSectionOffset() != null) + { + return 2; + } + + if( _value.getSectionNumber() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000023L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Received> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Received value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getSectionNumber(); + + case 1: + return _value.getSectionOffset(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Received> FACTORY = new Factory<Received>() + { + + public ValueWriter<Received> newInstance(Registry registry) + { + return new ReceivedWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Received.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedConstructor.java new file mode 100644 index 0000000000..eb923c535d --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.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.Rejected; + + +import java.util.List; + +public class RejectedConstructor extends DescribedTypeConstructor<Rejected> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:rejected:list"),UnsignedLong.valueOf(0x0000000000000025L), + }; + + private static final RejectedConstructor INSTANCE = new RejectedConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Rejected construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Rejected obj = new Rejected(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setError( (org.apache.qpid.amqp_1_0.type.transport.Error) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedWriter.java new file mode 100644 index 0000000000..6e24ac2972 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/RejectedWriter.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.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.Rejected; + +public class RejectedWriter extends AbstractDescribedTypeWriter<Rejected> +{ + private Rejected _value; + private int _count = -1; + + public RejectedWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Rejected value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getError() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000025L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Rejected> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Rejected value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getError(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Rejected> FACTORY = new Factory<Rejected>() + { + + public ValueWriter<Rejected> newInstance(Registry registry) + { + return new RejectedWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Rejected.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedConstructor.java new file mode 100644 index 0000000000..534b81efd7 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedConstructor.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.Released; + + +import java.util.List; + +public class ReleasedConstructor extends DescribedTypeConstructor<Released> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:released:list"),UnsignedLong.valueOf(0x0000000000000026L), + }; + + private static final ReleasedConstructor INSTANCE = new ReleasedConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Released construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Released obj = new Released(); + int position = 0; + final int size = list.size(); + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedWriter.java new file mode 100644 index 0000000000..cad602e0a6 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/ReleasedWriter.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.Released; + +public class ReleasedWriter extends AbstractDescribedTypeWriter<Released> +{ + private Released _value; + private int _count = -1; + + public ReleasedWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Released value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000026L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Released> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Released 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<Released> FACTORY = new Factory<Released>() + { + + public ValueWriter<Released> newInstance(Registry registry) + { + return new ReleasedWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Released.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceConstructor.java new file mode 100644 index 0000000000..764fa222ee --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceConstructor.java @@ -0,0 +1,384 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Source; + + +import java.util.List; +import java.util.Map; + +public class SourceConstructor extends DescribedTypeConstructor<Source> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:source:list"),UnsignedLong.valueOf(0x0000000000000028L), + }; + + private static final SourceConstructor INSTANCE = new SourceConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Source construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Source obj = new Source(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setAddress( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDurable( TerminusDurability.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setExpiryPolicy( TerminusExpiryPolicy.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTimeout( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDynamic( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDynamicNodeProperties( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDistributionMode( (DistributionMode) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setFilter( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDefaultOutcome( (Outcome) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setOutcomes( (Symbol[]) val ); + } + else + { + try + { + obj.setOutcomes( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceWriter.java new file mode 100644 index 0000000000..7fc8cfb35e --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/SourceWriter.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.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.Source; + +public class SourceWriter extends AbstractDescribedTypeWriter<Source> +{ + private Source _value; + private int _count = -1; + + public SourceWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Source value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getCapabilities() != null) + { + return 11; + } + + if( _value.getOutcomes() != null) + { + return 10; + } + + if( _value.getDefaultOutcome() != null) + { + return 9; + } + + if( _value.getFilter() != null) + { + return 8; + } + + if( _value.getDistributionMode() != null) + { + return 7; + } + + if( _value.getDynamicNodeProperties() != null) + { + return 6; + } + + if( _value.getDynamic() != null) + { + return 5; + } + + if( _value.getTimeout() != null) + { + return 4; + } + + if( _value.getExpiryPolicy() != null) + { + return 3; + } + + if( _value.getDurable() != null) + { + return 2; + } + + if( _value.getAddress() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000028L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Source> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Source value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getAddress(); + + case 1: + return _value.getDurable(); + + case 2: + return _value.getExpiryPolicy(); + + case 3: + return _value.getTimeout(); + + case 4: + return _value.getDynamic(); + + case 5: + return _value.getDynamicNodeProperties(); + + case 6: + return _value.getDistributionMode(); + + case 7: + return _value.getFilter(); + + case 8: + return _value.getDefaultOutcome(); + + case 9: + return _value.getOutcomes(); + + case 10: + return _value.getCapabilities(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Source> FACTORY = new Factory<Source>() + { + + public ValueWriter<Source> newInstance(Registry registry) + { + return new SourceWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Source.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetConstructor.java new file mode 100644 index 0000000000..1c89574273 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetConstructor.java @@ -0,0 +1,269 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Target; + + +import java.util.List; +import java.util.Map; + +public class TargetConstructor extends DescribedTypeConstructor<Target> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:target:list"),UnsignedLong.valueOf(0x0000000000000029L), + }; + + private static final TargetConstructor INSTANCE = new TargetConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Target construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Target obj = new Target(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setAddress( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDurable( TerminusDurability.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setExpiryPolicy( TerminusExpiryPolicy.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTimeout( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDynamic( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDynamicNodeProperties( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetWriter.java new file mode 100644 index 0000000000..970a9f4020 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/messaging/codec/TargetWriter.java @@ -0,0 +1,198 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.Target; + +public class TargetWriter extends AbstractDescribedTypeWriter<Target> +{ + private Target _value; + private int _count = -1; + + public TargetWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Target value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getCapabilities() != null) + { + return 7; + } + + if( _value.getDynamicNodeProperties() != null) + { + return 6; + } + + if( _value.getDynamic() != null) + { + return 5; + } + + if( _value.getTimeout() != null) + { + return 4; + } + + if( _value.getExpiryPolicy() != null) + { + return 3; + } + + if( _value.getDurable() != null) + { + return 2; + } + + if( _value.getAddress() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000029L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Target> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Target value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getAddress(); + + case 1: + return _value.getDurable(); + + case 2: + return _value.getExpiryPolicy(); + + case 3: + return _value.getTimeout(); + + case 4: + return _value.getDynamic(); + + case 5: + return _value.getDynamicNodeProperties(); + + case 6: + return _value.getCapabilities(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Target> FACTORY = new Factory<Target>() + { + + public ValueWriter<Target> newInstance(Registry registry) + { + return new TargetWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Target.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslChallenge.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslChallenge.java new file mode 100644 index 0000000000..081c00af29 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslChallenge.java @@ -0,0 +1,74 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security; + + +import org.apache.qpid.amqp_1_0.transport.SASLEndpoint; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SaslChallenge + implements SaslFrameBody + { + + + private Binary _challenge; + + public Binary getChallenge() + { + return _challenge; + } + + public void setChallenge(Binary challenge) + { + _challenge = challenge; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("SaslChallenge{"); + final int origLength = builder.length(); + + if(_challenge != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("challenge=").append(_challenge); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(SASLEndpoint conn) + { + conn.receiveSaslChallenge(this); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslCode.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslCode.java new file mode 100644 index 0000000000..59a24070ef --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslCode.java @@ -0,0 +1,131 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SaslCode + implements RestrictedType<UnsignedByte> + + { + + + + private final UnsignedByte _val; + + + public static final SaslCode OK = new SaslCode(UnsignedByte.valueOf((byte) 0)); + + public static final SaslCode AUTH = new SaslCode(UnsignedByte.valueOf((byte) 1)); + + public static final SaslCode SYS = new SaslCode(UnsignedByte.valueOf((byte) 2)); + + public static final SaslCode SYS_PERM = new SaslCode(UnsignedByte.valueOf((byte) 3)); + + public static final SaslCode SYS_TEMP = new SaslCode(UnsignedByte.valueOf((byte) 4)); + + + + private SaslCode(UnsignedByte val) + { + _val = val; + } + + public UnsignedByte getValue() + { + return _val; + } + + public String toString() + { + + if(this == OK) + { + return "ok"; + } + + if(this == AUTH) + { + return "auth"; + } + + if(this == SYS) + { + return "sys"; + } + + if(this == SYS_PERM) + { + return "sys-perm"; + } + + if(this == SYS_TEMP) + { + return "sys-temp"; + } + + else + { + return String.valueOf(_val); + } + } + + public static SaslCode valueOf(Object obj) + { + UnsignedByte val = (UnsignedByte) obj; + + if(OK._val.equals(val)) + { + return OK; + } + + if(AUTH._val.equals(val)) + { + return AUTH; + } + + if(SYS._val.equals(val)) + { + return SYS; + } + + if(SYS_PERM._val.equals(val)) + { + return SYS_PERM; + } + + if(SYS_TEMP._val.equals(val)) + { + return SYS_TEMP; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslInit.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslInit.java new file mode 100644 index 0000000000..9b789a4e17 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslInit.java @@ -0,0 +1,116 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security; + + +import org.apache.qpid.amqp_1_0.transport.SASLEndpoint; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SaslInit + implements SaslFrameBody + { + + + private Symbol _mechanism; + + private Binary _initialResponse; + + private String _hostname; + + public Symbol getMechanism() + { + return _mechanism; + } + + public void setMechanism(Symbol mechanism) + { + _mechanism = mechanism; + } + + public Binary getInitialResponse() + { + return _initialResponse; + } + + public void setInitialResponse(Binary initialResponse) + { + _initialResponse = initialResponse; + } + + public String getHostname() + { + return _hostname; + } + + public void setHostname(String hostname) + { + _hostname = hostname; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("SaslInit{"); + final int origLength = builder.length(); + + if(_mechanism != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("mechanism=").append(_mechanism); + } + + if(_initialResponse != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("initialResponse=").append(_initialResponse); + } + + if(_hostname != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("hostname=").append(_hostname); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(SASLEndpoint conn) + { + conn.receiveSaslInit(this); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslMechanisms.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslMechanisms.java new file mode 100644 index 0000000000..7f4775c3ae --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslMechanisms.java @@ -0,0 +1,74 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security; + + +import org.apache.qpid.amqp_1_0.transport.SASLEndpoint; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SaslMechanisms + implements SaslFrameBody + { + + + private Symbol[] _saslServerMechanisms; + + public Symbol[] getSaslServerMechanisms() + { + return _saslServerMechanisms; + } + + public void setSaslServerMechanisms(Symbol[] saslServerMechanisms) + { + _saslServerMechanisms = saslServerMechanisms; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("SaslMechanisms{"); + final int origLength = builder.length(); + + if(_saslServerMechanisms != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("saslServerMechanisms=").append(_saslServerMechanisms); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(SASLEndpoint conn) + { + conn.receiveSaslMechanisms(this); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslOutcome.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslOutcome.java new file mode 100644 index 0000000000..02d707d311 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslOutcome.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.security; + + +import org.apache.qpid.amqp_1_0.transport.SASLEndpoint; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SaslOutcome + implements SaslFrameBody + { + + + private SaslCode _code; + + private Binary _additionalData; + + public SaslCode getCode() + { + return _code; + } + + public void setCode(SaslCode code) + { + _code = code; + } + + public Binary getAdditionalData() + { + return _additionalData; + } + + public void setAdditionalData(Binary additionalData) + { + _additionalData = additionalData; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("SaslOutcome{"); + final int origLength = builder.length(); + + if(_code != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("code=").append(_code); + } + + if(_additionalData != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("additionalData=").append(_additionalData); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(SASLEndpoint conn) + { + conn.receiveSaslOutcome(this); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslResponse.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslResponse.java new file mode 100644 index 0000000000..7ffcaba7e9 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/SaslResponse.java @@ -0,0 +1,74 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security; + + +import org.apache.qpid.amqp_1_0.transport.SASLEndpoint; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SaslResponse + implements SaslFrameBody + { + + + private Binary _response; + + public Binary getResponse() + { + return _response; + } + + public void setResponse(Binary response) + { + _response = response; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("SaslResponse{"); + final int origLength = builder.length(); + + if(_response != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("response=").append(_response); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(SASLEndpoint conn) + { + conn.receiveSaslResponse(this); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeConstructor.java new file mode 100644 index 0000000000..400e62db5a --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.security.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.security.*; +import org.apache.qpid.amqp_1_0.type.security.SaslChallenge; + + +import java.util.List; + +public class SaslChallengeConstructor extends DescribedTypeConstructor<SaslChallenge> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:sasl-challenge:list"),UnsignedLong.valueOf(0x0000000000000042L), + }; + + private static final SaslChallengeConstructor INSTANCE = new SaslChallengeConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public SaslChallenge construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + SaslChallenge obj = new SaslChallenge(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setChallenge( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeWriter.java new file mode 100644 index 0000000000..2dd0e572e4 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslChallengeWriter.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.type.security.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.security.SaslChallenge; + +public class SaslChallengeWriter extends AbstractDescribedTypeWriter<SaslChallenge> +{ + private SaslChallenge _value; + private int _count = -1; + + public SaslChallengeWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslChallenge value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getChallenge() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000042L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<SaslChallenge> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslChallenge value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getChallenge(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<SaslChallenge> FACTORY = new Factory<SaslChallenge>() + { + + public ValueWriter<SaslChallenge> newInstance(Registry registry) + { + return new SaslChallengeWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(SaslChallenge.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitConstructor.java new file mode 100644 index 0000000000..ff21c8e7d9 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitConstructor.java @@ -0,0 +1,153 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security.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.security.*; +import org.apache.qpid.amqp_1_0.type.security.SaslInit; + + +import java.util.List; + +public class SaslInitConstructor extends DescribedTypeConstructor<SaslInit> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:sasl-init:list"),UnsignedLong.valueOf(0x0000000000000041L), + }; + + private static final SaslInitConstructor INSTANCE = new SaslInitConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public SaslInit construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + SaslInit obj = new SaslInit(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMechanism( (Symbol) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setInitialResponse( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHostname( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitWriter.java new file mode 100644 index 0000000000..50c724d9ed --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslInitWriter.java @@ -0,0 +1,166 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security.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.security.SaslInit; + +public class SaslInitWriter extends AbstractDescribedTypeWriter<SaslInit> +{ + private SaslInit _value; + private int _count = -1; + + public SaslInitWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslInit value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getHostname() != null) + { + return 3; + } + + if( _value.getInitialResponse() != null) + { + return 2; + } + + if( _value.getMechanism() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000041L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<SaslInit> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslInit value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getMechanism(); + + case 1: + return _value.getInitialResponse(); + + case 2: + return _value.getHostname(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<SaslInit> FACTORY = new Factory<SaslInit>() + { + + public ValueWriter<SaslInit> newInstance(Registry registry) + { + return new SaslInitWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(SaslInit.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsConstructor.java new file mode 100644 index 0000000000..0fcdbd2a1a --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsConstructor.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.type.security.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.security.*; +import org.apache.qpid.amqp_1_0.type.security.SaslMechanisms; + + +import java.util.List; + +public class SaslMechanismsConstructor extends DescribedTypeConstructor<SaslMechanisms> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:sasl-mechanisms:list"),UnsignedLong.valueOf(0x0000000000000040L), + }; + + private static final SaslMechanismsConstructor INSTANCE = new SaslMechanismsConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public SaslMechanisms construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + SaslMechanisms obj = new SaslMechanisms(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setSaslServerMechanisms( (Symbol[]) val ); + } + else + { + try + { + obj.setSaslServerMechanisms( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsWriter.java new file mode 100644 index 0000000000..e630cd0a2f --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslMechanismsWriter.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.type.security.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.security.SaslMechanisms; + +public class SaslMechanismsWriter extends AbstractDescribedTypeWriter<SaslMechanisms> +{ + private SaslMechanisms _value; + private int _count = -1; + + public SaslMechanismsWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslMechanisms value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getSaslServerMechanisms() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000040L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<SaslMechanisms> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslMechanisms value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getSaslServerMechanisms(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<SaslMechanisms> FACTORY = new Factory<SaslMechanisms>() + { + + public ValueWriter<SaslMechanisms> newInstance(Registry registry) + { + return new SaslMechanismsWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(SaslMechanisms.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeConstructor.java new file mode 100644 index 0000000000..b1c4760d3e --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeConstructor.java @@ -0,0 +1,126 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security.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.security.*; +import org.apache.qpid.amqp_1_0.type.security.SaslOutcome; + + +import java.util.List; + +public class SaslOutcomeConstructor extends DescribedTypeConstructor<SaslOutcome> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:sasl-outcome:list"),UnsignedLong.valueOf(0x0000000000000044L), + }; + + private static final SaslOutcomeConstructor INSTANCE = new SaslOutcomeConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public SaslOutcome construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + SaslOutcome obj = new SaslOutcome(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setCode( SaslCode.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setAdditionalData( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeWriter.java new file mode 100644 index 0000000000..7c35900ccc --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslOutcomeWriter.java @@ -0,0 +1,158 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.security.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.security.SaslOutcome; + +public class SaslOutcomeWriter extends AbstractDescribedTypeWriter<SaslOutcome> +{ + private SaslOutcome _value; + private int _count = -1; + + public SaslOutcomeWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslOutcome value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getAdditionalData() != null) + { + return 2; + } + + if( _value.getCode() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000044L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<SaslOutcome> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslOutcome value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getCode(); + + case 1: + return _value.getAdditionalData(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<SaslOutcome> FACTORY = new Factory<SaslOutcome>() + { + + public ValueWriter<SaslOutcome> newInstance(Registry registry) + { + return new SaslOutcomeWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(SaslOutcome.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseConstructor.java new file mode 100644 index 0000000000..364cf59a2f --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.security.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.security.*; +import org.apache.qpid.amqp_1_0.type.security.SaslResponse; + + +import java.util.List; + +public class SaslResponseConstructor extends DescribedTypeConstructor<SaslResponse> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:sasl-response:list"),UnsignedLong.valueOf(0x0000000000000043L), + }; + + private static final SaslResponseConstructor INSTANCE = new SaslResponseConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public SaslResponse construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + SaslResponse obj = new SaslResponse(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setResponse( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseWriter.java new file mode 100644 index 0000000000..a8d63085c2 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/security/codec/SaslResponseWriter.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.type.security.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.security.SaslResponse; + +public class SaslResponseWriter extends AbstractDescribedTypeWriter<SaslResponse> +{ + private SaslResponse _value; + private int _count = -1; + + public SaslResponseWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslResponse value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getResponse() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000043L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<SaslResponse> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final SaslResponse value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getResponse(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<SaslResponse> FACTORY = new Factory<SaslResponse>() + { + + public ValueWriter<SaslResponse> newInstance(Registry registry) + { + return new SaslResponseWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(SaslResponse.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Coordinator.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Coordinator.java new file mode 100644 index 0000000000..0417cefd35 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Coordinator.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.transaction; + + + +import java.util.Arrays; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Coordinator + implements Target + { + + + private TxnCapability[] _capabilities; + + public TxnCapability[] getCapabilities() + { + return _capabilities; + } + + public void setCapabilities(TxnCapability[] capabilities) + { + _capabilities = capabilities; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Coordinator{"); + final int origLength = builder.length(); + + if(_capabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("capabilities=").append(Arrays.asList(_capabilities)); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declare.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declare.java new file mode 100644 index 0000000000..5ec8993392 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declare.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.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Declare + { + + + private GlobalTxId _globalId; + + public GlobalTxId getGlobalId() + { + return _globalId; + } + + public void setGlobalId(GlobalTxId globalId) + { + _globalId = globalId; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Declare{"); + final int origLength = builder.length(); + + if(_globalId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("globalId=").append(_globalId); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declared.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declared.java new file mode 100644 index 0000000000..4878cc3ccf --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Declared.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.type.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Declared + implements DeliveryState, Outcome + { + + + private Binary _txnId; + + public Binary getTxnId() + { + return _txnId; + } + + public void setTxnId(Binary txnId) + { + _txnId = txnId; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Declared{"); + final int origLength = builder.length(); + + if(_txnId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("txnId=").append(_txnId); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Discharge.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Discharge.java new file mode 100644 index 0000000000..356380608b --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/Discharge.java @@ -0,0 +1,87 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Discharge + { + + + private Binary _txnId; + + private Boolean _fail; + + public Binary getTxnId() + { + return _txnId; + } + + public void setTxnId(Binary txnId) + { + _txnId = txnId; + } + + public Boolean getFail() + { + return _fail; + } + + public void setFail(Boolean fail) + { + _fail = fail; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Discharge{"); + final int origLength = builder.length(); + + if(_txnId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("txnId=").append(_txnId); + } + + if(_fail != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("fail=").append(_fail); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionErrors.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionErrors.java new file mode 100644 index 0000000000..b87a7eea91 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionErrors.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.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class TransactionErrors + implements ErrorCondition, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final TransactionErrors UNKNOWN_ID = new TransactionErrors(Symbol.valueOf("amqp:transaction:unknown-id")); + + public static final TransactionErrors TRANSACTION_ROLLBACK = new TransactionErrors(Symbol.valueOf("amqp:transaction:rollback")); + + public static final TransactionErrors TRANSACTION_TIMEOUT = new TransactionErrors(Symbol.valueOf("amqp:transaction:timeout")); + + + + private TransactionErrors(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == UNKNOWN_ID) + { + return "unknown-id"; + } + + if(this == TRANSACTION_ROLLBACK) + { + return "transaction-rollback"; + } + + if(this == TRANSACTION_TIMEOUT) + { + return "transaction-timeout"; + } + + else + { + return String.valueOf(_val); + } + } + + public static TransactionErrors valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(UNKNOWN_ID._val.equals(val)) + { + return UNKNOWN_ID; + } + + if(TRANSACTION_ROLLBACK._val.equals(val)) + { + return TRANSACTION_ROLLBACK; + } + + if(TRANSACTION_TIMEOUT._val.equals(val)) + { + return TRANSACTION_TIMEOUT; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionalState.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionalState.java new file mode 100644 index 0000000000..b4fe564cf1 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TransactionalState.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.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class TransactionalState + implements DeliveryState + { + + + private Binary _txnId; + + private Outcome _outcome; + + public Binary getTxnId() + { + return _txnId; + } + + public void setTxnId(Binary txnId) + { + _txnId = txnId; + } + + public Outcome getOutcome() + { + return _outcome; + } + + public void setOutcome(Outcome outcome) + { + _outcome = outcome; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("TransactionalState{"); + final int origLength = builder.length(); + + if(_txnId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("txnId=").append(_txnId); + } + + if(_outcome != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("outcome=").append(_outcome); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapabilities.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapabilities.java new file mode 100644 index 0000000000..840cc57d27 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapabilities.java @@ -0,0 +1,144 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; +import org.apache.qpid.amqp_1_0.type.TxnCapability; + +public class TxnCapabilities + implements TxnCapability, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final TxnCapabilities LOCAL_TXN = new TxnCapabilities(Symbol.valueOf("amqp:local-transactions")); + + public static final TxnCapabilities DISTRIBUTED_TXN = new TxnCapabilities(Symbol.valueOf("amqp:distributed-transactions")); + + public static final TxnCapabilities PROMOTABLE_TXN = new TxnCapabilities(Symbol.valueOf("amqp:promotable-transactions")); + + public static final TxnCapabilities MULTI_TXNS_PER_SSN = new TxnCapabilities(Symbol.valueOf("amqp:multi-txns-per-ssn")); + + public static final TxnCapabilities MULTI_SSNS_PER_TXN = new TxnCapabilities(Symbol.valueOf("amqp:multi-ssns-per-txn")); + + public static final TxnCapabilities MULTI_CONNS_PER_TXN = new TxnCapabilities(Symbol.valueOf("amqp:multi-conns-per-txn")); + + + + private TxnCapabilities(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == LOCAL_TXN) + { + return "local-txn"; + } + + if(this == DISTRIBUTED_TXN) + { + return "distributed-txn"; + } + + if(this == PROMOTABLE_TXN) + { + return "promotable-txn"; + } + + if(this == MULTI_TXNS_PER_SSN) + { + return "multi-txns-per-ssn"; + } + + if(this == MULTI_SSNS_PER_TXN) + { + return "multi-ssns-per-txn"; + } + + if(this == MULTI_CONNS_PER_TXN) + { + return "multi-conns-per-txn"; + } + + else + { + return String.valueOf(_val); + } + } + + public static TxnCapabilities valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(LOCAL_TXN._val.equals(val)) + { + return LOCAL_TXN; + } + + if(DISTRIBUTED_TXN._val.equals(val)) + { + return DISTRIBUTED_TXN; + } + + if(PROMOTABLE_TXN._val.equals(val)) + { + return PROMOTABLE_TXN; + } + + if(MULTI_TXNS_PER_SSN._val.equals(val)) + { + return MULTI_TXNS_PER_SSN; + } + + if(MULTI_SSNS_PER_TXN._val.equals(val)) + { + return MULTI_SSNS_PER_TXN; + } + + if(MULTI_CONNS_PER_TXN._val.equals(val)) + { + return MULTI_CONNS_PER_TXN; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapability.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapability.java new file mode 100644 index 0000000000..19763f5b6b --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/TxnCapability.java @@ -0,0 +1,131 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class TxnCapability + implements org.apache.qpid.amqp_1_0.type.TxnCapability, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final TxnCapability LOCAL_TXN = new TxnCapability(Symbol.valueOf("amqp:local-transactions")); + + public static final TxnCapability DISTRIBUTED_TXN = new TxnCapability(Symbol.valueOf("amqp:distributed-transactions")); + + public static final TxnCapability PROMOTABLE_TXN = new TxnCapability(Symbol.valueOf("amqp:promotable-transactions")); + + public static final TxnCapability MULTI_TXNS_PER_SSN = new TxnCapability(Symbol.valueOf("amqp:multi-txns-per-ssn")); + + public static final TxnCapability MULTI_SSNS_PER_TXN = new TxnCapability(Symbol.valueOf("amqp:multi-ssns-per-txn")); + + + + private TxnCapability(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == LOCAL_TXN) + { + return "local-txn"; + } + + if(this == DISTRIBUTED_TXN) + { + return "distributed-txn"; + } + + if(this == PROMOTABLE_TXN) + { + return "promotable-txn"; + } + + if(this == MULTI_TXNS_PER_SSN) + { + return "multi-txns-per-ssn"; + } + + if(this == MULTI_SSNS_PER_TXN) + { + return "multi-ssns-per-txn"; + } + + else + { + return String.valueOf(_val); + } + } + + public static TxnCapability valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(LOCAL_TXN._val.equals(val)) + { + return LOCAL_TXN; + } + + if(DISTRIBUTED_TXN._val.equals(val)) + { + return DISTRIBUTED_TXN; + } + + if(PROMOTABLE_TXN._val.equals(val)) + { + return PROMOTABLE_TXN; + } + + if(MULTI_TXNS_PER_SSN._val.equals(val)) + { + return MULTI_TXNS_PER_SSN; + } + + if(MULTI_SSNS_PER_TXN._val.equals(val)) + { + return MULTI_SSNS_PER_TXN; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorConstructor.java new file mode 100644 index 0000000000..de1dbc625e --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorConstructor.java @@ -0,0 +1,117 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction.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.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.Coordinator; +import org.apache.qpid.amqp_1_0.type.transaction.TxnCapability; + +import java.util.List; + +public class CoordinatorConstructor extends DescribedTypeConstructor<Coordinator> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:coordinator:list"),UnsignedLong.valueOf(0x0000000000000030L), + }; + + private static final CoordinatorConstructor INSTANCE = new CoordinatorConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Coordinator construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Coordinator obj = new Coordinator(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof TxnCapability[] ) + { + obj.setCapabilities( (TxnCapability[]) val ); + } + else if (val instanceof Symbol[]) + { + Symbol[] symVal = (Symbol[]) val; + TxnCapability[] cap = new TxnCapability[symVal.length]; + int i = 0; + for(Symbol sym : symVal) + { + cap[i++] = TxnCapability.valueOf(sym); + } + obj.setCapabilities(cap); + } + else + { + try + { + obj.setCapabilities( new TxnCapability[] { (TxnCapability) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorWriter.java new file mode 100644 index 0000000000..56e3993046 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/CoordinatorWriter.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.type.transaction.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.transaction.Coordinator; + +public class CoordinatorWriter extends AbstractDescribedTypeWriter<Coordinator> +{ + private Coordinator _value; + private int _count = -1; + + public CoordinatorWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Coordinator value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getCapabilities() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000030L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Coordinator> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Coordinator value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getCapabilities(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Coordinator> FACTORY = new Factory<Coordinator>() + { + + public ValueWriter<Coordinator> newInstance(Registry registry) + { + return new CoordinatorWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Coordinator.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareConstructor.java new file mode 100644 index 0000000000..7eaf7dd9a8 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.transaction.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.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.Declare; + + +import java.util.List; + +public class DeclareConstructor extends DescribedTypeConstructor<Declare> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:declare:list"),UnsignedLong.valueOf(0x0000000000000031L), + }; + + private static final DeclareConstructor INSTANCE = new DeclareConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Declare construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Declare obj = new Declare(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setGlobalId( (GlobalTxId) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareWriter.java new file mode 100644 index 0000000000..bf0687fe92 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclareWriter.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.type.transaction.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.transaction.Declare; + +public class DeclareWriter extends AbstractDescribedTypeWriter<Declare> +{ + private Declare _value; + private int _count = -1; + + public DeclareWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Declare value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getGlobalId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000031L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Declare> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Declare value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getGlobalId(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Declare> FACTORY = new Factory<Declare>() + { + + public ValueWriter<Declare> newInstance(Registry registry) + { + return new DeclareWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Declare.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredConstructor.java new file mode 100644 index 0000000000..1e226ff994 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.transaction.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.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.Declared; + + +import java.util.List; + +public class DeclaredConstructor extends DescribedTypeConstructor<Declared> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:declared:list"),UnsignedLong.valueOf(0x0000000000000033L), + }; + + private static final DeclaredConstructor INSTANCE = new DeclaredConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Declared construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Declared obj = new Declared(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTxnId( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredWriter.java new file mode 100644 index 0000000000..798ffcc72b --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DeclaredWriter.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.type.transaction.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.transaction.Declared; + +public class DeclaredWriter extends AbstractDescribedTypeWriter<Declared> +{ + private Declared _value; + private int _count = -1; + + public DeclaredWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Declared value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getTxnId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000033L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Declared> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Declared value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getTxnId(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Declared> FACTORY = new Factory<Declared>() + { + + public ValueWriter<Declared> newInstance(Registry registry) + { + return new DeclaredWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Declared.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeConstructor.java new file mode 100644 index 0000000000..ab088cc74d --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeConstructor.java @@ -0,0 +1,126 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction.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.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.Discharge; + + +import java.util.List; + +public class DischargeConstructor extends DescribedTypeConstructor<Discharge> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:discharge:list"),UnsignedLong.valueOf(0x0000000000000032L), + }; + + private static final DischargeConstructor INSTANCE = new DischargeConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Discharge construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Discharge obj = new Discharge(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTxnId( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setFail( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeWriter.java new file mode 100644 index 0000000000..ddd8678418 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/DischargeWriter.java @@ -0,0 +1,158 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction.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.transaction.Discharge; + +public class DischargeWriter extends AbstractDescribedTypeWriter<Discharge> +{ + private Discharge _value; + private int _count = -1; + + public DischargeWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Discharge value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getFail() != null) + { + return 2; + } + + if( _value.getTxnId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000032L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Discharge> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Discharge value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getTxnId(); + + case 1: + return _value.getFail(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Discharge> FACTORY = new Factory<Discharge>() + { + + public ValueWriter<Discharge> newInstance(Registry registry) + { + return new DischargeWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Discharge.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateConstructor.java new file mode 100644 index 0000000000..88cddba562 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateConstructor.java @@ -0,0 +1,126 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction.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.transaction.*; +import org.apache.qpid.amqp_1_0.type.transaction.TransactionalState; + + +import java.util.List; + +public class TransactionalStateConstructor extends DescribedTypeConstructor<TransactionalState> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:transactional-state:list"),UnsignedLong.valueOf(0x0000000000000034L), + }; + + private static final TransactionalStateConstructor INSTANCE = new TransactionalStateConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public TransactionalState construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + TransactionalState obj = new TransactionalState(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTxnId( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setOutcome( (Outcome) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateWriter.java new file mode 100644 index 0000000000..ea450fcf35 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transaction/codec/TransactionalStateWriter.java @@ -0,0 +1,158 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transaction.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.transaction.TransactionalState; + +public class TransactionalStateWriter extends AbstractDescribedTypeWriter<TransactionalState> +{ + private TransactionalState _value; + private int _count = -1; + + public TransactionalStateWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final TransactionalState value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getOutcome() != null) + { + return 2; + } + + if( _value.getTxnId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000034L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<TransactionalState> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final TransactionalState value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getTxnId(); + + case 1: + return _value.getOutcome(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<TransactionalState> FACTORY = new Factory<TransactionalState>() + { + + public ValueWriter<TransactionalState> newInstance(Registry registry) + { + return new TransactionalStateWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(TransactionalState.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/AmqpError.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/AmqpError.java new file mode 100644 index 0000000000..075a80ef90 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/AmqpError.java @@ -0,0 +1,227 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class AmqpError + implements ErrorCondition, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final AmqpError INTERNAL_ERROR = new AmqpError(Symbol.valueOf("amqp:internal-error")); + + public static final AmqpError NOT_FOUND = new AmqpError(Symbol.valueOf("amqp:not-found")); + + public static final AmqpError UNAUTHORIZED_ACCESS = new AmqpError(Symbol.valueOf("amqp:unauthorized-access")); + + public static final AmqpError DECODE_ERROR = new AmqpError(Symbol.valueOf("amqp:decode-error")); + + public static final AmqpError RESOURCE_LIMIT_EXCEEDED = new AmqpError(Symbol.valueOf("amqp:resource-limit-exceeded")); + + public static final AmqpError NOT_ALLOWED = new AmqpError(Symbol.valueOf("amqp:not-allowed")); + + public static final AmqpError INVALID_FIELD = new AmqpError(Symbol.valueOf("amqp:invalid-field")); + + public static final AmqpError NOT_IMPLEMENTED = new AmqpError(Symbol.valueOf("amqp:not-implemented")); + + public static final AmqpError RESOURCE_LOCKED = new AmqpError(Symbol.valueOf("amqp:resource-locked")); + + public static final AmqpError PRECONDITION_FAILED = new AmqpError(Symbol.valueOf("amqp:precondition-failed")); + + public static final AmqpError RESOURCE_DELETED = new AmqpError(Symbol.valueOf("amqp:resource-deleted")); + + public static final AmqpError ILLEGAL_STATE = new AmqpError(Symbol.valueOf("amqp:illegal-state")); + + public static final AmqpError FRAME_SIZE_TOO_SMALL = new AmqpError(Symbol.valueOf("amqp:frame-size-too-small")); + + + + private AmqpError(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == INTERNAL_ERROR) + { + return "internal-error"; + } + + if(this == NOT_FOUND) + { + return "not-found"; + } + + if(this == UNAUTHORIZED_ACCESS) + { + return "unauthorized-access"; + } + + if(this == DECODE_ERROR) + { + return "decode-error"; + } + + if(this == RESOURCE_LIMIT_EXCEEDED) + { + return "resource-limit-exceeded"; + } + + if(this == NOT_ALLOWED) + { + return "not-allowed"; + } + + if(this == INVALID_FIELD) + { + return "invalid-field"; + } + + if(this == NOT_IMPLEMENTED) + { + return "not-implemented"; + } + + if(this == RESOURCE_LOCKED) + { + return "resource-locked"; + } + + if(this == PRECONDITION_FAILED) + { + return "precondition-failed"; + } + + if(this == RESOURCE_DELETED) + { + return "resource-deleted"; + } + + if(this == ILLEGAL_STATE) + { + return "illegal-state"; + } + + if(this == FRAME_SIZE_TOO_SMALL) + { + return "frame-size-too-small"; + } + + else + { + return String.valueOf(_val); + } + } + + public static AmqpError valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(INTERNAL_ERROR._val.equals(val)) + { + return INTERNAL_ERROR; + } + + if(NOT_FOUND._val.equals(val)) + { + return NOT_FOUND; + } + + if(UNAUTHORIZED_ACCESS._val.equals(val)) + { + return UNAUTHORIZED_ACCESS; + } + + if(DECODE_ERROR._val.equals(val)) + { + return DECODE_ERROR; + } + + if(RESOURCE_LIMIT_EXCEEDED._val.equals(val)) + { + return RESOURCE_LIMIT_EXCEEDED; + } + + if(NOT_ALLOWED._val.equals(val)) + { + return NOT_ALLOWED; + } + + if(INVALID_FIELD._val.equals(val)) + { + return INVALID_FIELD; + } + + if(NOT_IMPLEMENTED._val.equals(val)) + { + return NOT_IMPLEMENTED; + } + + if(RESOURCE_LOCKED._val.equals(val)) + { + return RESOURCE_LOCKED; + } + + if(PRECONDITION_FAILED._val.equals(val)) + { + return PRECONDITION_FAILED; + } + + if(RESOURCE_DELETED._val.equals(val)) + { + return RESOURCE_DELETED; + } + + if(ILLEGAL_STATE._val.equals(val)) + { + return ILLEGAL_STATE; + } + + if(FRAME_SIZE_TOO_SMALL._val.equals(val)) + { + return FRAME_SIZE_TOO_SMALL; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Attach.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Attach.java new file mode 100644 index 0000000000..d01dd0146c --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Attach.java @@ -0,0 +1,365 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.util.Map; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Attach + implements FrameBody + { + + + private ByteBuffer _payload; + + private String _name; + + private UnsignedInteger _handle; + + private Role _role; + + private SenderSettleMode _sndSettleMode; + + private ReceiverSettleMode _rcvSettleMode; + + private Source _source; + + private Target _target; + + private Map _unsettled; + + private Boolean _incompleteUnsettled; + + private UnsignedInteger _initialDeliveryCount; + + private UnsignedLong _maxMessageSize; + + private Symbol[] _offeredCapabilities; + + private Symbol[] _desiredCapabilities; + + private Map _properties; + + public String getName() + { + return _name; + } + + public void setName(String name) + { + _name = name; + } + + public UnsignedInteger getHandle() + { + return _handle; + } + + public void setHandle(UnsignedInteger handle) + { + _handle = handle; + } + + public Role getRole() + { + return _role; + } + + public void setRole(Role role) + { + _role = role; + } + + public SenderSettleMode getSndSettleMode() + { + return _sndSettleMode; + } + + public void setSndSettleMode(SenderSettleMode sndSettleMode) + { + _sndSettleMode = sndSettleMode; + } + + public ReceiverSettleMode getRcvSettleMode() + { + return _rcvSettleMode; + } + + public void setRcvSettleMode(ReceiverSettleMode rcvSettleMode) + { + _rcvSettleMode = rcvSettleMode; + } + + public Source getSource() + { + return _source; + } + + public void setSource(Source source) + { + _source = source; + } + + public Target getTarget() + { + return _target; + } + + public void setTarget(Target target) + { + _target = target; + } + + public Map getUnsettled() + { + return _unsettled; + } + + public void setUnsettled(Map unsettled) + { + _unsettled = unsettled; + } + + public Boolean getIncompleteUnsettled() + { + return _incompleteUnsettled; + } + + public void setIncompleteUnsettled(Boolean incompleteUnsettled) + { + _incompleteUnsettled = incompleteUnsettled; + } + + public UnsignedInteger getInitialDeliveryCount() + { + return _initialDeliveryCount; + } + + public void setInitialDeliveryCount(UnsignedInteger initialDeliveryCount) + { + _initialDeliveryCount = initialDeliveryCount; + } + + public UnsignedLong getMaxMessageSize() + { + return _maxMessageSize; + } + + public void setMaxMessageSize(UnsignedLong maxMessageSize) + { + _maxMessageSize = maxMessageSize; + } + + public Symbol[] getOfferedCapabilities() + { + return _offeredCapabilities; + } + + public void setOfferedCapabilities(Symbol[] offeredCapabilities) + { + _offeredCapabilities = offeredCapabilities; + } + + public Symbol[] getDesiredCapabilities() + { + return _desiredCapabilities; + } + + public void setDesiredCapabilities(Symbol[] desiredCapabilities) + { + _desiredCapabilities = desiredCapabilities; + } + + public Map getProperties() + { + return _properties; + } + + public void setProperties(Map properties) + { + _properties = properties; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Attach{"); + final int origLength = builder.length(); + + if(_name != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("name=").append(_name); + } + + if(_handle != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("handle=").append(_handle); + } + + if(_role != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("role=").append(_role); + } + + if(_sndSettleMode != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("sndSettleMode=").append(_sndSettleMode); + } + + if(_rcvSettleMode != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("rcvSettleMode=").append(_rcvSettleMode); + } + + if(_source != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("source=").append(_source); + } + + if(_target != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("target=").append(_target); + } + + if(_unsettled != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("unsettled=").append(_unsettled); + } + + if(_incompleteUnsettled != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("incompleteUnsettled=").append(_incompleteUnsettled); + } + + if(_initialDeliveryCount != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("initialDeliveryCount=").append(_initialDeliveryCount); + } + + if(_maxMessageSize != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("maxMessageSize=").append(_maxMessageSize); + } + + if(_offeredCapabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("offeredCapabilities=").append(_offeredCapabilities); + } + + if(_desiredCapabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("desiredCapabilities=").append(_desiredCapabilities); + } + + if(_properties != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("properties=").append(_properties); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveAttach(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Begin.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Begin.java new file mode 100644 index 0000000000..558fcbf780 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Begin.java @@ -0,0 +1,239 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.util.Map; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Begin + implements FrameBody + { + + + private ByteBuffer _payload; + + private UnsignedShort _remoteChannel; + + private UnsignedInteger _nextOutgoingId; + + private UnsignedInteger _incomingWindow; + + private UnsignedInteger _outgoingWindow; + + private UnsignedInteger _handleMax; + + private Symbol[] _offeredCapabilities; + + private Symbol[] _desiredCapabilities; + + private Map _properties; + + public UnsignedShort getRemoteChannel() + { + return _remoteChannel; + } + + public void setRemoteChannel(UnsignedShort remoteChannel) + { + _remoteChannel = remoteChannel; + } + + public UnsignedInteger getNextOutgoingId() + { + return _nextOutgoingId; + } + + public void setNextOutgoingId(UnsignedInteger nextOutgoingId) + { + _nextOutgoingId = nextOutgoingId; + } + + public UnsignedInteger getIncomingWindow() + { + return _incomingWindow; + } + + public void setIncomingWindow(UnsignedInteger incomingWindow) + { + _incomingWindow = incomingWindow; + } + + public UnsignedInteger getOutgoingWindow() + { + return _outgoingWindow; + } + + public void setOutgoingWindow(UnsignedInteger outgoingWindow) + { + _outgoingWindow = outgoingWindow; + } + + public UnsignedInteger getHandleMax() + { + return _handleMax; + } + + public void setHandleMax(UnsignedInteger handleMax) + { + _handleMax = handleMax; + } + + public Symbol[] getOfferedCapabilities() + { + return _offeredCapabilities; + } + + public void setOfferedCapabilities(Symbol[] offeredCapabilities) + { + _offeredCapabilities = offeredCapabilities; + } + + public Symbol[] getDesiredCapabilities() + { + return _desiredCapabilities; + } + + public void setDesiredCapabilities(Symbol[] desiredCapabilities) + { + _desiredCapabilities = desiredCapabilities; + } + + public Map getProperties() + { + return _properties; + } + + public void setProperties(Map properties) + { + _properties = properties; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Begin{"); + final int origLength = builder.length(); + + if(_remoteChannel != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("remoteChannel=").append(_remoteChannel); + } + + if(_nextOutgoingId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("nextOutgoingId=").append(_nextOutgoingId); + } + + if(_incomingWindow != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("incomingWindow=").append(_incomingWindow); + } + + if(_outgoingWindow != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("outgoingWindow=").append(_outgoingWindow); + } + + if(_handleMax != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("handleMax=").append(_handleMax); + } + + if(_offeredCapabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("offeredCapabilities=").append(_offeredCapabilities); + } + + if(_desiredCapabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("desiredCapabilities=").append(_desiredCapabilities); + } + + if(_properties != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("properties=").append(_properties); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveBegin(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Close.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Close.java new file mode 100644 index 0000000000..e86342d531 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Close.java @@ -0,0 +1,89 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Close + implements FrameBody + { + + + private ByteBuffer _payload; + + private Error _error; + + public Error getError() + { + return _error; + } + + public void setError(Error error) + { + _error = error; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Close{"); + final int origLength = builder.length(); + + if(_error != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("error=").append(_error); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveClose(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ConnectionError.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ConnectionError.java new file mode 100644 index 0000000000..07f0496e23 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ConnectionError.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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class ConnectionError + implements ErrorCondition, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final ConnectionError CONNECTION_FORCED = new ConnectionError(Symbol.valueOf("amqp:connection:forced")); + + public static final ConnectionError FRAMING_ERROR = new ConnectionError(Symbol.valueOf("amqp:connection:framing-error")); + + public static final ConnectionError REDIRECT = new ConnectionError(Symbol.valueOf("amqp:connection:redirect")); + + + + private ConnectionError(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == CONNECTION_FORCED) + { + return "connection-forced"; + } + + if(this == FRAMING_ERROR) + { + return "framing-error"; + } + + if(this == REDIRECT) + { + return "redirect"; + } + + else + { + return String.valueOf(_val); + } + } + + public static ConnectionError valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(CONNECTION_FORCED._val.equals(val)) + { + return CONNECTION_FORCED; + } + + if(FRAMING_ERROR._val.equals(val)) + { + return FRAMING_ERROR; + } + + if(REDIRECT._val.equals(val)) + { + return REDIRECT; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Detach.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Detach.java new file mode 100644 index 0000000000..f788201328 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Detach.java @@ -0,0 +1,131 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Detach + implements FrameBody + { + + + private ByteBuffer _payload; + + private UnsignedInteger _handle; + + private Boolean _closed; + + private Error _error; + + public UnsignedInteger getHandle() + { + return _handle; + } + + public void setHandle(UnsignedInteger handle) + { + _handle = handle; + } + + public Boolean getClosed() + { + return _closed; + } + + public void setClosed(Boolean closed) + { + _closed = closed; + } + + public Error getError() + { + return _error; + } + + public void setError(Error error) + { + _error = error; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Detach{"); + final int origLength = builder.length(); + + if(_handle != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("handle=").append(_handle); + } + + if(_closed != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("closed=").append(_closed); + } + + if(_error != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("error=").append(_error); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveDetach(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Disposition.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Disposition.java new file mode 100644 index 0000000000..c7f04dedca --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Disposition.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.type.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Disposition + implements FrameBody + { + + + private ByteBuffer _payload; + + private Role _role; + + private UnsignedInteger _first; + + private UnsignedInteger _last; + + private Boolean _settled; + + private DeliveryState _state; + + private Boolean _batchable; + + public Role getRole() + { + return _role; + } + + public void setRole(Role role) + { + _role = role; + } + + public UnsignedInteger getFirst() + { + return _first; + } + + public void setFirst(UnsignedInteger first) + { + _first = first; + } + + public UnsignedInteger getLast() + { + return _last; + } + + public void setLast(UnsignedInteger last) + { + _last = last; + } + + public Boolean getSettled() + { + return _settled; + } + + public void setSettled(Boolean settled) + { + _settled = settled; + } + + public DeliveryState getState() + { + return _state; + } + + public void setState(DeliveryState state) + { + _state = state; + } + + public Boolean getBatchable() + { + return _batchable; + } + + public void setBatchable(Boolean batchable) + { + _batchable = batchable; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Disposition{"); + final int origLength = builder.length(); + + if(_role != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("role=").append(_role); + } + + if(_first != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("first=").append(_first); + } + + if(_last != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("last=").append(_last); + } + + if(_settled != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("settled=").append(_settled); + } + + if(_state != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("state=").append(_state); + } + + if(_batchable != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("batchable=").append(_batchable); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveDisposition(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/End.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/End.java new file mode 100644 index 0000000000..63fc331360 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/End.java @@ -0,0 +1,89 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class End + implements FrameBody + { + + + private ByteBuffer _payload; + + private Error _error; + + public Error getError() + { + return _error; + } + + public void setError(Error error) + { + _error = error; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("End{"); + final int origLength = builder.length(); + + if(_error != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("error=").append(_error); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveEnd(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.java new file mode 100644 index 0000000000..6e1af84cc9 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Error.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.type.transport; + + + +import java.util.Map; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Error + { + + + private ErrorCondition _condition; + + private String _description; + + private Map _info; + + public ErrorCondition getCondition() + { + return _condition; + } + + public void setCondition(ErrorCondition condition) + { + _condition = condition; + } + + public String getDescription() + { + return _description; + } + + public void setDescription(String description) + { + _description = description; + } + + public Map getInfo() + { + return _info; + } + + public void setInfo(Map info) + { + _info = info; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Error{"); + final int origLength = builder.length(); + + if(_condition != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("condition=").append(_condition); + } + + if(_description != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("description=").append(_description); + } + + if(_info != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("info=").append(_info); + } + + builder.append('}'); + return builder.toString(); + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Flow.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Flow.java new file mode 100644 index 0000000000..118d163841 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Flow.java @@ -0,0 +1,302 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.util.Map; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Flow + implements FrameBody + { + + + private ByteBuffer _payload; + + private UnsignedInteger _nextIncomingId; + + private UnsignedInteger _incomingWindow; + + private UnsignedInteger _nextOutgoingId; + + private UnsignedInteger _outgoingWindow; + + private UnsignedInteger _handle; + + private UnsignedInteger _deliveryCount; + + private UnsignedInteger _linkCredit; + + private UnsignedInteger _available; + + private Boolean _drain; + + private Boolean _echo; + + private Map _properties; + + public UnsignedInteger getNextIncomingId() + { + return _nextIncomingId; + } + + public void setNextIncomingId(UnsignedInteger nextIncomingId) + { + _nextIncomingId = nextIncomingId; + } + + public UnsignedInteger getIncomingWindow() + { + return _incomingWindow; + } + + public void setIncomingWindow(UnsignedInteger incomingWindow) + { + _incomingWindow = incomingWindow; + } + + public UnsignedInteger getNextOutgoingId() + { + return _nextOutgoingId; + } + + public void setNextOutgoingId(UnsignedInteger nextOutgoingId) + { + _nextOutgoingId = nextOutgoingId; + } + + public UnsignedInteger getOutgoingWindow() + { + return _outgoingWindow; + } + + public void setOutgoingWindow(UnsignedInteger outgoingWindow) + { + _outgoingWindow = outgoingWindow; + } + + public UnsignedInteger getHandle() + { + return _handle; + } + + public void setHandle(UnsignedInteger handle) + { + _handle = handle; + } + + public UnsignedInteger getDeliveryCount() + { + return _deliveryCount; + } + + public void setDeliveryCount(UnsignedInteger deliveryCount) + { + _deliveryCount = deliveryCount; + } + + public UnsignedInteger getLinkCredit() + { + return _linkCredit; + } + + public void setLinkCredit(UnsignedInteger linkCredit) + { + _linkCredit = linkCredit; + } + + public UnsignedInteger getAvailable() + { + return _available; + } + + public void setAvailable(UnsignedInteger available) + { + _available = available; + } + + public Boolean getDrain() + { + return _drain; + } + + public void setDrain(Boolean drain) + { + _drain = drain; + } + + public Boolean getEcho() + { + return _echo; + } + + public void setEcho(Boolean echo) + { + _echo = echo; + } + + public Map getProperties() + { + return _properties; + } + + public void setProperties(Map properties) + { + _properties = properties; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Flow{"); + final int origLength = builder.length(); + + if(_nextIncomingId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("nextIncomingId=").append(_nextIncomingId); + } + + if(_incomingWindow != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("incomingWindow=").append(_incomingWindow); + } + + if(_nextOutgoingId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("nextOutgoingId=").append(_nextOutgoingId); + } + + if(_outgoingWindow != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("outgoingWindow=").append(_outgoingWindow); + } + + if(_handle != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("handle=").append(_handle); + } + + if(_deliveryCount != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("deliveryCount=").append(_deliveryCount); + } + + if(_linkCredit != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("linkCredit=").append(_linkCredit); + } + + if(_available != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("available=").append(_available); + } + + if(_drain != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("drain=").append(_drain); + } + + if(_echo != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("echo=").append(_echo); + } + + if(_properties != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("properties=").append(_properties); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveFlow(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/LinkError.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/LinkError.java new file mode 100644 index 0000000000..3c2d025619 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/LinkError.java @@ -0,0 +1,131 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class LinkError + implements ErrorCondition, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final LinkError DETACH_FORCED = new LinkError(Symbol.valueOf("amqp:link:detach-forced")); + + public static final LinkError TRANSFER_LIMIT_EXCEEDED = new LinkError(Symbol.valueOf("amqp:link:transfer-limit-exceeded")); + + public static final LinkError MESSAGE_SIZE_EXCEEDED = new LinkError(Symbol.valueOf("amqp:link:message-size-exceeded")); + + public static final LinkError REDIRECT = new LinkError(Symbol.valueOf("amqp:link:redirect")); + + public static final LinkError STOLEN = new LinkError(Symbol.valueOf("amqp:link:stolen")); + + + + private LinkError(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == DETACH_FORCED) + { + return "detach-forced"; + } + + if(this == TRANSFER_LIMIT_EXCEEDED) + { + return "transfer-limit-exceeded"; + } + + if(this == MESSAGE_SIZE_EXCEEDED) + { + return "message-size-exceeded"; + } + + if(this == REDIRECT) + { + return "redirect"; + } + + if(this == STOLEN) + { + return "stolen"; + } + + else + { + return String.valueOf(_val); + } + } + + public static LinkError valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(DETACH_FORCED._val.equals(val)) + { + return DETACH_FORCED; + } + + if(TRANSFER_LIMIT_EXCEEDED._val.equals(val)) + { + return TRANSFER_LIMIT_EXCEEDED; + } + + if(MESSAGE_SIZE_EXCEEDED._val.equals(val)) + { + return MESSAGE_SIZE_EXCEEDED; + } + + if(REDIRECT._val.equals(val)) + { + return REDIRECT; + } + + if(STOLEN._val.equals(val)) + { + return STOLEN; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Open.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Open.java new file mode 100644 index 0000000000..cabee25c73 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Open.java @@ -0,0 +1,281 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.util.Map; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Open + implements FrameBody + { + + + private ByteBuffer _payload; + + private String _containerId; + + private String _hostname; + + private UnsignedInteger _maxFrameSize; + + private UnsignedShort _channelMax; + + private UnsignedInteger _idleTimeOut; + + private Symbol[] _outgoingLocales; + + private Symbol[] _incomingLocales; + + private Symbol[] _offeredCapabilities; + + private Symbol[] _desiredCapabilities; + + private Map _properties; + + public String getContainerId() + { + return _containerId; + } + + public void setContainerId(String containerId) + { + _containerId = containerId; + } + + public String getHostname() + { + return _hostname; + } + + public void setHostname(String hostname) + { + _hostname = hostname; + } + + public UnsignedInteger getMaxFrameSize() + { + return _maxFrameSize; + } + + public void setMaxFrameSize(UnsignedInteger maxFrameSize) + { + _maxFrameSize = maxFrameSize; + } + + public UnsignedShort getChannelMax() + { + return _channelMax; + } + + public void setChannelMax(UnsignedShort channelMax) + { + _channelMax = channelMax; + } + + public UnsignedInteger getIdleTimeOut() + { + return _idleTimeOut; + } + + public void setIdleTimeOut(UnsignedInteger idleTimeOut) + { + _idleTimeOut = idleTimeOut; + } + + public Symbol[] getOutgoingLocales() + { + return _outgoingLocales; + } + + public void setOutgoingLocales(Symbol[] outgoingLocales) + { + _outgoingLocales = outgoingLocales; + } + + public Symbol[] getIncomingLocales() + { + return _incomingLocales; + } + + public void setIncomingLocales(Symbol[] incomingLocales) + { + _incomingLocales = incomingLocales; + } + + public Symbol[] getOfferedCapabilities() + { + return _offeredCapabilities; + } + + public void setOfferedCapabilities(Symbol[] offeredCapabilities) + { + _offeredCapabilities = offeredCapabilities; + } + + public Symbol[] getDesiredCapabilities() + { + return _desiredCapabilities; + } + + public void setDesiredCapabilities(Symbol[] desiredCapabilities) + { + _desiredCapabilities = desiredCapabilities; + } + + public Map getProperties() + { + return _properties; + } + + public void setProperties(Map properties) + { + _properties = properties; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Open{"); + final int origLength = builder.length(); + + if(_containerId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("containerId=").append(_containerId); + } + + if(_hostname != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("hostname=").append(_hostname); + } + + if(_maxFrameSize != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("maxFrameSize=").append(_maxFrameSize); + } + + if(_channelMax != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("channelMax=").append(_channelMax); + } + + if(_idleTimeOut != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("idleTimeOut=").append(_idleTimeOut); + } + + if(_outgoingLocales != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("outgoingLocales=").append(_outgoingLocales); + } + + if(_incomingLocales != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("incomingLocales=").append(_incomingLocales); + } + + if(_offeredCapabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("offeredCapabilities=").append(_offeredCapabilities); + } + + if(_desiredCapabilities != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("desiredCapabilities=").append(_desiredCapabilities); + } + + if(_properties != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("properties=").append(_properties); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveOpen(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ReceiverSettleMode.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ReceiverSettleMode.java new file mode 100644 index 0000000000..53f0f2b931 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/ReceiverSettleMode.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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class ReceiverSettleMode + implements RestrictedType<UnsignedByte> + + { + + + + private final UnsignedByte _val; + + + public static final ReceiverSettleMode FIRST = new ReceiverSettleMode(UnsignedByte.valueOf((byte) 0)); + + public static final ReceiverSettleMode SECOND = new ReceiverSettleMode(UnsignedByte.valueOf((byte) 1)); + + + + private ReceiverSettleMode(UnsignedByte val) + { + _val = val; + } + + public UnsignedByte getValue() + { + return _val; + } + + public String toString() + { + + if(this == FIRST) + { + return "first"; + } + + if(this == SECOND) + { + return "second"; + } + + else + { + return String.valueOf(_val); + } + } + + public static ReceiverSettleMode valueOf(Object obj) + { + UnsignedByte val = (UnsignedByte) obj; + + if(FIRST._val.equals(val)) + { + return FIRST; + } + + if(SECOND._val.equals(val)) + { + return SECOND; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Role.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Role.java new file mode 100644 index 0000000000..55be00b3d7 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Role.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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Role + implements RestrictedType<Boolean> + + { + + + + private final boolean _val; + + + public static final Role SENDER = new Role(false); + + public static final Role RECEIVER = new Role(true); + + + + private Role(boolean val) + { + _val = val; + } + + public Boolean getValue() + { + return _val; + } + + public String toString() + { + + if(this == SENDER) + { + return "sender"; + } + + if(this == RECEIVER) + { + return "receiver"; + } + + else + { + return String.valueOf(_val); + } + } + + public static Role valueOf(Object obj) + { + boolean val = (Boolean) obj; + + if(SENDER._val == (val)) + { + return SENDER; + } + + if(RECEIVER._val == (val)) + { + return RECEIVER; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SenderSettleMode.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SenderSettleMode.java new file mode 100644 index 0000000000..528ec69dbc --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SenderSettleMode.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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SenderSettleMode + implements RestrictedType<UnsignedByte> + + { + + + + private final UnsignedByte _val; + + + public static final SenderSettleMode UNSETTLED = new SenderSettleMode(UnsignedByte.valueOf((byte) 0)); + + public static final SenderSettleMode SETTLED = new SenderSettleMode(UnsignedByte.valueOf((byte) 1)); + + public static final SenderSettleMode MIXED = new SenderSettleMode(UnsignedByte.valueOf((byte) 2)); + + + + private SenderSettleMode(UnsignedByte val) + { + _val = val; + } + + public UnsignedByte getValue() + { + return _val; + } + + public String toString() + { + + if(this == UNSETTLED) + { + return "unsettled"; + } + + if(this == SETTLED) + { + return "settled"; + } + + if(this == MIXED) + { + return "mixed"; + } + + else + { + return String.valueOf(_val); + } + } + + public static SenderSettleMode valueOf(Object obj) + { + UnsignedByte val = (UnsignedByte) obj; + + if(UNSETTLED._val.equals(val)) + { + return UNSETTLED; + } + + if(SETTLED._val.equals(val)) + { + return SETTLED; + } + + if(MIXED._val.equals(val)) + { + return MIXED; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SessionError.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SessionError.java new file mode 100644 index 0000000000..b7b233c879 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/SessionError.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.transport; + + + +import org.apache.qpid.amqp_1_0.type.*; + +public class SessionError + implements ErrorCondition, RestrictedType<Symbol> + + { + + + + private final Symbol _val; + + + public static final SessionError WINDOW_VIOLATION = new SessionError(Symbol.valueOf("amqp:session:window-violation")); + + public static final SessionError ERRANT_LINK = new SessionError(Symbol.valueOf("amqp:session:errant-link")); + + public static final SessionError HANDLE_IN_USE = new SessionError(Symbol.valueOf("amqp:session:handle-in-use")); + + public static final SessionError UNATTACHED_HANDLE = new SessionError(Symbol.valueOf("amqp:session:unattached-handle")); + + + + private SessionError(Symbol val) + { + _val = val; + } + + public Symbol getValue() + { + return _val; + } + + public String toString() + { + + if(this == WINDOW_VIOLATION) + { + return "window-violation"; + } + + if(this == ERRANT_LINK) + { + return "errant-link"; + } + + if(this == HANDLE_IN_USE) + { + return "handle-in-use"; + } + + if(this == UNATTACHED_HANDLE) + { + return "unattached-handle"; + } + + else + { + return String.valueOf(_val); + } + } + + public static SessionError valueOf(Object obj) + { + Symbol val = (Symbol) obj; + + if(WINDOW_VIOLATION._val.equals(val)) + { + return WINDOW_VIOLATION; + } + + if(ERRANT_LINK._val.equals(val)) + { + return ERRANT_LINK; + } + + if(HANDLE_IN_USE._val.equals(val)) + { + return HANDLE_IN_USE; + } + + if(UNATTACHED_HANDLE._val.equals(val)) + { + return UNATTACHED_HANDLE; + } + + // TODO ERROR + return null; + } + + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Transfer.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Transfer.java new file mode 100644 index 0000000000..a58db63a1f --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/Transfer.java @@ -0,0 +1,299 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport; + + +import org.apache.qpid.amqp_1_0.transport.ConnectionEndpoint; + + +import java.nio.ByteBuffer; + + +import org.apache.qpid.amqp_1_0.type.*; + +public class Transfer + implements FrameBody + { + + + private ByteBuffer _payload; + + private UnsignedInteger _handle; + + private UnsignedInteger _deliveryId; + + private Binary _deliveryTag; + + private UnsignedInteger _messageFormat; + + private Boolean _settled; + + private Boolean _more; + + private ReceiverSettleMode _rcvSettleMode; + + private DeliveryState _state; + + private Boolean _resume; + + private Boolean _aborted; + + private Boolean _batchable; + + public UnsignedInteger getHandle() + { + return _handle; + } + + public void setHandle(UnsignedInteger handle) + { + _handle = handle; + } + + public UnsignedInteger getDeliveryId() + { + return _deliveryId; + } + + public void setDeliveryId(UnsignedInteger deliveryId) + { + _deliveryId = deliveryId; + } + + public Binary getDeliveryTag() + { + return _deliveryTag; + } + + public void setDeliveryTag(Binary deliveryTag) + { + _deliveryTag = deliveryTag; + } + + public UnsignedInteger getMessageFormat() + { + return _messageFormat; + } + + public void setMessageFormat(UnsignedInteger messageFormat) + { + _messageFormat = messageFormat; + } + + public Boolean getSettled() + { + return _settled; + } + + public void setSettled(Boolean settled) + { + _settled = settled; + } + + public Boolean getMore() + { + return _more; + } + + public void setMore(Boolean more) + { + _more = more; + } + + public ReceiverSettleMode getRcvSettleMode() + { + return _rcvSettleMode; + } + + public void setRcvSettleMode(ReceiverSettleMode rcvSettleMode) + { + _rcvSettleMode = rcvSettleMode; + } + + public DeliveryState getState() + { + return _state; + } + + public void setState(DeliveryState state) + { + _state = state; + } + + public Boolean getResume() + { + return _resume; + } + + public void setResume(Boolean resume) + { + _resume = resume; + } + + public Boolean getAborted() + { + return _aborted; + } + + public void setAborted(Boolean aborted) + { + _aborted = aborted; + } + + public Boolean getBatchable() + { + return _batchable; + } + + public void setBatchable(Boolean batchable) + { + _batchable = batchable; + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder("Transfer{"); + final int origLength = builder.length(); + + if(_handle != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("handle=").append(_handle); + } + + if(_deliveryId != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("deliveryId=").append(_deliveryId); + } + + if(_deliveryTag != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("deliveryTag=").append(_deliveryTag); + } + + if(_messageFormat != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("messageFormat=").append(_messageFormat); + } + + if(_settled != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("settled=").append(_settled); + } + + if(_more != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("more=").append(_more); + } + + if(_rcvSettleMode != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("rcvSettleMode=").append(_rcvSettleMode); + } + + if(_state != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("state=").append(_state); + } + + if(_resume != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("resume=").append(_resume); + } + + if(_aborted != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("aborted=").append(_aborted); + } + + if(_batchable != null) + { + if(builder.length() != origLength) + { + builder.append(','); + } + builder.append("batchable=").append(_batchable); + } + + builder.append('}'); + return builder.toString(); + } + + public void invoke(short channel, ConnectionEndpoint conn) + { + conn.receiveTransfer(channel, this); + } + + public void setPayload(ByteBuffer payload) + { + _payload = payload; + } + + public ByteBuffer getPayload() + { + return _payload; + } + + + } diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachConstructor.java new file mode 100644 index 0000000000..0df84ac820 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachConstructor.java @@ -0,0 +1,465 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Attach; + + +import java.util.List; +import java.util.Map; + +public class AttachConstructor extends DescribedTypeConstructor<Attach> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:attach:list"),UnsignedLong.valueOf(0x0000000000000012L), + }; + + private static final AttachConstructor INSTANCE = new AttachConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Attach construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Attach obj = new Attach(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setName( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHandle( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setRole( Role.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSndSettleMode( SenderSettleMode.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setRcvSettleMode( ReceiverSettleMode.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSource( (Source) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setTarget( (Target) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setUnsettled( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setIncompleteUnsettled( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setInitialDeliveryCount( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMaxMessageSize( (UnsignedLong) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setOfferedCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setOfferedCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setDesiredCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setDesiredCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setProperties( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachWriter.java new file mode 100644 index 0000000000..0b67635dc0 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/AttachWriter.java @@ -0,0 +1,254 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.Attach; + +public class AttachWriter extends AbstractDescribedTypeWriter<Attach> +{ + private Attach _value; + private int _count = -1; + + public AttachWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Attach value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getProperties() != null) + { + return 14; + } + + if( _value.getDesiredCapabilities() != null) + { + return 13; + } + + if( _value.getOfferedCapabilities() != null) + { + return 12; + } + + if( _value.getMaxMessageSize() != null) + { + return 11; + } + + if( _value.getInitialDeliveryCount() != null) + { + return 10; + } + + if( _value.getIncompleteUnsettled() != null) + { + return 9; + } + + if( _value.getUnsettled() != null) + { + return 8; + } + + if( _value.getTarget() != null) + { + return 7; + } + + if( _value.getSource() != null) + { + return 6; + } + + if( _value.getRcvSettleMode() != null) + { + return 5; + } + + if( _value.getSndSettleMode() != null) + { + return 4; + } + + if( _value.getRole() != null) + { + return 3; + } + + if( _value.getHandle() != null) + { + return 2; + } + + if( _value.getName() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000012L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Attach> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Attach value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getName(); + + case 1: + return _value.getHandle(); + + case 2: + return _value.getRole(); + + case 3: + return _value.getSndSettleMode(); + + case 4: + return _value.getRcvSettleMode(); + + case 5: + return _value.getSource(); + + case 6: + return _value.getTarget(); + + case 7: + return _value.getUnsettled(); + + case 8: + return _value.getIncompleteUnsettled(); + + case 9: + return _value.getInitialDeliveryCount(); + + case 10: + return _value.getMaxMessageSize(); + + case 11: + return _value.getOfferedCapabilities(); + + case 12: + return _value.getDesiredCapabilities(); + + case 13: + return _value.getProperties(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Attach> FACTORY = new Factory<Attach>() + { + + public ValueWriter<Attach> newInstance(Registry registry) + { + return new AttachWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Attach.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginConstructor.java new file mode 100644 index 0000000000..94470c5139 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginConstructor.java @@ -0,0 +1,303 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Begin; + + +import java.util.List; +import java.util.Map; + +public class BeginConstructor extends DescribedTypeConstructor<Begin> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:begin:list"),UnsignedLong.valueOf(0x0000000000000011L), + }; + + private static final BeginConstructor INSTANCE = new BeginConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Begin construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Begin obj = new Begin(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setRemoteChannel( (UnsignedShort) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setNextOutgoingId( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setIncomingWindow( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setOutgoingWindow( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHandleMax( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setOfferedCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setOfferedCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setDesiredCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setDesiredCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setProperties( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginWriter.java new file mode 100644 index 0000000000..84abf6698e --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/BeginWriter.java @@ -0,0 +1,206 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.Begin; + +public class BeginWriter extends AbstractDescribedTypeWriter<Begin> +{ + private Begin _value; + private int _count = -1; + + public BeginWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Begin value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getProperties() != null) + { + return 8; + } + + if( _value.getDesiredCapabilities() != null) + { + return 7; + } + + if( _value.getOfferedCapabilities() != null) + { + return 6; + } + + if( _value.getHandleMax() != null) + { + return 5; + } + + if( _value.getOutgoingWindow() != null) + { + return 4; + } + + if( _value.getIncomingWindow() != null) + { + return 3; + } + + if( _value.getNextOutgoingId() != null) + { + return 2; + } + + if( _value.getRemoteChannel() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000011L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Begin> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Begin value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getRemoteChannel(); + + case 1: + return _value.getNextOutgoingId(); + + case 2: + return _value.getIncomingWindow(); + + case 3: + return _value.getOutgoingWindow(); + + case 4: + return _value.getHandleMax(); + + case 5: + return _value.getOfferedCapabilities(); + + case 6: + return _value.getDesiredCapabilities(); + + case 7: + return _value.getProperties(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Begin> FACTORY = new Factory<Begin>() + { + + public ValueWriter<Begin> newInstance(Registry registry) + { + return new BeginWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Begin.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseConstructor.java new file mode 100644 index 0000000000..69544dc96f --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Close; + + +import java.util.List; + +public class CloseConstructor extends DescribedTypeConstructor<Close> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:close:list"),UnsignedLong.valueOf(0x0000000000000018L), + }; + + private static final CloseConstructor INSTANCE = new CloseConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Close construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Close obj = new Close(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setError( (org.apache.qpid.amqp_1_0.type.transport.Error) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseWriter.java new file mode 100644 index 0000000000..96313efcb9 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/CloseWriter.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.type.transport.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.transport.Close; + +public class CloseWriter extends AbstractDescribedTypeWriter<Close> +{ + private Close _value; + private int _count = -1; + + public CloseWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Close value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getError() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000018L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Close> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Close value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getError(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Close> FACTORY = new Factory<Close>() + { + + public ValueWriter<Close> newInstance(Registry registry) + { + return new CloseWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Close.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachConstructor.java new file mode 100644 index 0000000000..8d90d39769 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachConstructor.java @@ -0,0 +1,153 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Detach; + + +import java.util.List; + +public class DetachConstructor extends DescribedTypeConstructor<Detach> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:detach:list"),UnsignedLong.valueOf(0x0000000000000016L), + }; + + private static final DetachConstructor INSTANCE = new DetachConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Detach construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Detach obj = new Detach(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHandle( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setClosed( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setError( (org.apache.qpid.amqp_1_0.type.transport.Error) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachWriter.java new file mode 100644 index 0000000000..620f087f98 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DetachWriter.java @@ -0,0 +1,166 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.Detach; + +public class DetachWriter extends AbstractDescribedTypeWriter<Detach> +{ + private Detach _value; + private int _count = -1; + + public DetachWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Detach value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getError() != null) + { + return 3; + } + + if( _value.getClosed() != null) + { + return 2; + } + + if( _value.getHandle() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000016L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Detach> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Detach value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getHandle(); + + case 1: + return _value.getClosed(); + + case 2: + return _value.getError(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Detach> FACTORY = new Factory<Detach>() + { + + public ValueWriter<Detach> newInstance(Registry registry) + { + return new DetachWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Detach.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionConstructor.java new file mode 100644 index 0000000000..928f54ea97 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionConstructor.java @@ -0,0 +1,234 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Disposition; + + +import java.util.List; + +public class DispositionConstructor extends DescribedTypeConstructor<Disposition> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:disposition:list"),UnsignedLong.valueOf(0x0000000000000015L), + }; + + private static final DispositionConstructor INSTANCE = new DispositionConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Disposition construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Disposition obj = new Disposition(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setRole( Role.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setFirst( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setLast( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSettled( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setState( (DeliveryState) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setBatchable( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionWriter.java new file mode 100644 index 0000000000..3bfdf840ab --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/DispositionWriter.java @@ -0,0 +1,190 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.Disposition; + +public class DispositionWriter extends AbstractDescribedTypeWriter<Disposition> +{ + private Disposition _value; + private int _count = -1; + + public DispositionWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Disposition value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getBatchable() != null) + { + return 6; + } + + if( _value.getState() != null) + { + return 5; + } + + if( _value.getSettled() != null) + { + return 4; + } + + if( _value.getLast() != null) + { + return 3; + } + + if( _value.getFirst() != null) + { + return 2; + } + + if( _value.getRole() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000015L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Disposition> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Disposition value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getRole(); + + case 1: + return _value.getFirst(); + + case 2: + return _value.getLast(); + + case 3: + return _value.getSettled(); + + case 4: + return _value.getState(); + + case 5: + return _value.getBatchable(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Disposition> FACTORY = new Factory<Disposition>() + { + + public ValueWriter<Disposition> newInstance(Registry registry) + { + return new DispositionWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Disposition.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndConstructor.java new file mode 100644 index 0000000000..0f8fe63d55 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndConstructor.java @@ -0,0 +1,99 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ + + +package org.apache.qpid.amqp_1_0.type.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.End; + + +import java.util.List; + +public class EndConstructor extends DescribedTypeConstructor<End> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:end:list"),UnsignedLong.valueOf(0x0000000000000017L), + }; + + private static final EndConstructor INSTANCE = new EndConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public End construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + End obj = new End(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setError( (org.apache.qpid.amqp_1_0.type.transport.Error) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndWriter.java new file mode 100644 index 0000000000..af6a11ae09 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/EndWriter.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.type.transport.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.transport.End; + +public class EndWriter extends AbstractDescribedTypeWriter<End> +{ + private End _value; + private int _count = -1; + + public EndWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final End value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getError() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000017L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<End> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final End value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getError(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<End> FACTORY = new Factory<End>() + { + + public ValueWriter<End> newInstance(Registry registry) + { + return new EndWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(End.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorConstructor.java new file mode 100644 index 0000000000..6d745adb7e --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorConstructor.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.type.transport.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.transaction.TransactionErrors; +import org.apache.qpid.amqp_1_0.type.transport.*; + + +import java.util.List; +import java.util.Map; + +public class ErrorConstructor extends DescribedTypeConstructor<org.apache.qpid.amqp_1_0.type.transport.Error> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:error:list"),UnsignedLong.valueOf(0x000000000000001dL), + }; + + private static final ErrorConstructor INSTANCE = new ErrorConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public org.apache.qpid.amqp_1_0.type.transport.Error construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + org.apache.qpid.amqp_1_0.type.transport.Error obj = new org.apache.qpid.amqp_1_0.type.transport.Error(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + if(val instanceof ErrorCondition) + { + obj.setCondition( (ErrorCondition) val ); + } + else if(val instanceof Symbol) + { + ErrorCondition condition = null; + condition = AmqpError.valueOf(val); + if(condition == null) + { + condition = ConnectionError.valueOf(val); + if(condition == null) + { + condition = SessionError.valueOf(val); + if(condition == null) + { + condition = LinkError.valueOf(val); + if(condition == null) + { + condition = TransactionErrors.valueOf(val); + } + } + } + } + obj.setCondition(condition); + } + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDescription( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setInfo( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorWriter.java new file mode 100644 index 0000000000..6c5ebc5dc6 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/ErrorWriter.java @@ -0,0 +1,166 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.Error; + +public class ErrorWriter extends AbstractDescribedTypeWriter<Error> +{ + private Error _value; + private int _count = -1; + + public ErrorWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Error value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getInfo() != null) + { + return 3; + } + + if( _value.getDescription() != null) + { + return 2; + } + + if( _value.getCondition() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x000000000000001dL); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Error> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Error value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getCondition(); + + case 1: + return _value.getDescription(); + + case 2: + return _value.getInfo(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Error> FACTORY = new Factory<Error>() + { + + public ValueWriter<Error> newInstance(Registry registry) + { + return new ErrorWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Error.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowConstructor.java new file mode 100644 index 0000000000..406b5a327a --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowConstructor.java @@ -0,0 +1,370 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Flow; + + +import java.util.List; +import java.util.Map; + +public class FlowConstructor extends DescribedTypeConstructor<Flow> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:flow:list"),UnsignedLong.valueOf(0x0000000000000013L), + }; + + private static final FlowConstructor INSTANCE = new FlowConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Flow construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Flow obj = new Flow(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setNextIncomingId( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setIncomingWindow( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setNextOutgoingId( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setOutgoingWindow( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHandle( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDeliveryCount( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setLinkCredit( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setAvailable( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDrain( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setEcho( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setProperties( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowWriter.java new file mode 100644 index 0000000000..a866491cea --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/FlowWriter.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.type.transport.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.transport.Flow; + +public class FlowWriter extends AbstractDescribedTypeWriter<Flow> +{ + private Flow _value; + private int _count = -1; + + public FlowWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Flow value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getProperties() != null) + { + return 11; + } + + if( _value.getEcho() != null) + { + return 10; + } + + if( _value.getDrain() != null) + { + return 9; + } + + if( _value.getAvailable() != null) + { + return 8; + } + + if( _value.getLinkCredit() != null) + { + return 7; + } + + if( _value.getDeliveryCount() != null) + { + return 6; + } + + if( _value.getHandle() != null) + { + return 5; + } + + if( _value.getOutgoingWindow() != null) + { + return 4; + } + + if( _value.getNextOutgoingId() != null) + { + return 3; + } + + if( _value.getIncomingWindow() != null) + { + return 2; + } + + if( _value.getNextIncomingId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000013L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Flow> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Flow value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getNextIncomingId(); + + case 1: + return _value.getIncomingWindow(); + + case 2: + return _value.getNextOutgoingId(); + + case 3: + return _value.getOutgoingWindow(); + + case 4: + return _value.getHandle(); + + case 5: + return _value.getDeliveryCount(); + + case 6: + return _value.getLinkCredit(); + + case 7: + return _value.getAvailable(); + + case 8: + return _value.getDrain(); + + case 9: + return _value.getEcho(); + + case 10: + return _value.getProperties(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Flow> FACTORY = new Factory<Flow>() + { + + public ValueWriter<Flow> newInstance(Registry registry) + { + return new FlowWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Flow.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenConstructor.java new file mode 100644 index 0000000000..ba2df038e4 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenConstructor.java @@ -0,0 +1,371 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Open; + + +import java.util.List; +import java.util.Map; + +public class OpenConstructor extends DescribedTypeConstructor<Open> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:open:list"),UnsignedLong.valueOf(0x0000000000000010L), + }; + + private static final OpenConstructor INSTANCE = new OpenConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Open construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Open obj = new Open(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setContainerId( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHostname( (String) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMaxFrameSize( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setChannelMax( (UnsignedShort) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setIdleTimeOut( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setOutgoingLocales( (Symbol[]) val ); + } + else + { + try + { + obj.setOutgoingLocales( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setIncomingLocales( (Symbol[]) val ); + } + else + { + try + { + obj.setIncomingLocales( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setOfferedCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setOfferedCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + + if (val instanceof Symbol[] ) + { + obj.setDesiredCapabilities( (Symbol[]) val ); + } + else + { + try + { + obj.setDesiredCapabilities( new Symbol[] { (Symbol) val } ); + } + catch(ClassCastException e) + { + // TODO Error + } + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setProperties( (Map) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenWriter.java new file mode 100644 index 0000000000..f512384a20 --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/OpenWriter.java @@ -0,0 +1,222 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.Open; + +public class OpenWriter extends AbstractDescribedTypeWriter<Open> +{ + private Open _value; + private int _count = -1; + + public OpenWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Open value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getProperties() != null) + { + return 10; + } + + if( _value.getDesiredCapabilities() != null) + { + return 9; + } + + if( _value.getOfferedCapabilities() != null) + { + return 8; + } + + if( _value.getIncomingLocales() != null) + { + return 7; + } + + if( _value.getOutgoingLocales() != null) + { + return 6; + } + + if( _value.getIdleTimeOut() != null) + { + return 5; + } + + if( _value.getChannelMax() != null) + { + return 4; + } + + if( _value.getMaxFrameSize() != null) + { + return 3; + } + + if( _value.getHostname() != null) + { + return 2; + } + + if( _value.getContainerId() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000010L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Open> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Open value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getContainerId(); + + case 1: + return _value.getHostname(); + + case 2: + return _value.getMaxFrameSize(); + + case 3: + return _value.getChannelMax(); + + case 4: + return _value.getIdleTimeOut(); + + case 5: + return _value.getOutgoingLocales(); + + case 6: + return _value.getIncomingLocales(); + + case 7: + return _value.getOfferedCapabilities(); + + case 8: + return _value.getDesiredCapabilities(); + + case 9: + return _value.getProperties(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Open> FACTORY = new Factory<Open>() + { + + public ValueWriter<Open> newInstance(Registry registry) + { + return new OpenWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Open.class, FACTORY); + } + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferConstructor.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferConstructor.java new file mode 100644 index 0000000000..ad3812bbdc --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferConstructor.java @@ -0,0 +1,369 @@ + +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either 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.transport.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.transport.*; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; + + +import java.util.List; + +public class TransferConstructor extends DescribedTypeConstructor<Transfer> +{ + private static final Object[] DESCRIPTORS = + { + Symbol.valueOf("amqp:transfer:list"),UnsignedLong.valueOf(0x0000000000000014L), + }; + + private static final TransferConstructor INSTANCE = new TransferConstructor(); + + public static void register(DescribedTypeConstructorRegistry registry) + { + for(Object descriptor : DESCRIPTORS) + { + registry.register(descriptor, INSTANCE); + } + } + + public Transfer construct(Object underlying) + { + if(underlying instanceof List) + { + List list = (List) underlying; + Transfer obj = new Transfer(); + int position = 0; + final int size = list.size(); + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setHandle( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDeliveryId( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setDeliveryTag( (Binary) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMessageFormat( (UnsignedInteger) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setSettled( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setMore( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setRcvSettleMode( ReceiverSettleMode.valueOf( val ) ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setState( (DeliveryState) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setResume( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setAborted( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + if(position < size) + { + Object val = list.get(position); + position++; + + if(val != null) + { + + try + { + obj.setBatchable( (Boolean) val ); + } + catch(ClassCastException e) + { + + // TODO Error + } + + } + + + } + else + { + return obj; + } + + + return obj; + } + else + { + // TODO - error + return null; + } + } + + +} diff --git a/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferWriter.java b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferWriter.java new file mode 100644 index 0000000000..f2252cfc4a --- /dev/null +++ b/qpid/java/amqp-1-0-common/src/main/java/org/apache/qpid/amqp_1_0/type/transport/codec/TransferWriter.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.type.transport.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.transport.Transfer; + +public class TransferWriter extends AbstractDescribedTypeWriter<Transfer> +{ + private Transfer _value; + private int _count = -1; + + public TransferWriter(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Transfer value) + { + _value = value; + _count = calculateCount(); + } + + private int calculateCount() + { + + + if( _value.getBatchable() != null) + { + return 11; + } + + if( _value.getAborted() != null) + { + return 10; + } + + if( _value.getResume() != null) + { + return 9; + } + + if( _value.getState() != null) + { + return 8; + } + + if( _value.getRcvSettleMode() != null) + { + return 7; + } + + if( _value.getMore() != null) + { + return 6; + } + + if( _value.getSettled() != null) + { + return 5; + } + + if( _value.getMessageFormat() != null) + { + return 4; + } + + if( _value.getDeliveryTag() != null) + { + return 3; + } + + if( _value.getDeliveryId() != null) + { + return 2; + } + + if( _value.getHandle() != null) + { + return 1; + } + + return 0; + } + + @Override + protected void clear() + { + _value = null; + _count = -1; + } + + + protected Object getDescriptor() + { + return UnsignedLong.valueOf(0x0000000000000014L); + } + + @Override + protected ValueWriter createDescribedWriter() + { + final Writer writer = new Writer(getRegistry()); + writer.setValue(_value); + return writer; + } + + private class Writer extends AbstractListWriter<Transfer> + { + private int _field; + + public Writer(final Registry registry) + { + super(registry); + } + + @Override + protected void onSetValue(final Transfer value) + { + reset(); + } + + @Override + protected int getCount() + { + return _count; + } + + @Override + protected boolean hasNext() + { + return _field < _count; + } + + @Override + protected Object next() + { + switch(_field++) + { + + case 0: + return _value.getHandle(); + + case 1: + return _value.getDeliveryId(); + + case 2: + return _value.getDeliveryTag(); + + case 3: + return _value.getMessageFormat(); + + case 4: + return _value.getSettled(); + + case 5: + return _value.getMore(); + + case 6: + return _value.getRcvSettleMode(); + + case 7: + return _value.getState(); + + case 8: + return _value.getResume(); + + case 9: + return _value.getAborted(); + + case 10: + return _value.getBatchable(); + + default: + return null; + } + } + + @Override + protected void clear() + { + } + + @Override + protected void reset() + { + _field = 0; + } + } + + private static Factory<Transfer> FACTORY = new Factory<Transfer>() + { + + public ValueWriter<Transfer> newInstance(Registry registry) + { + return new TransferWriter(registry); + } + }; + + public static void register(ValueWriter.Registry registry) + { + registry.register(Transfer.class, FACTORY); + } + +} diff --git a/qpid/java/broker/build.xml b/qpid/java/broker/build.xml index bb809583ee..9e8bf12f18 100644 --- a/qpid/java/broker/build.xml +++ b/qpid/java/broker/build.xml @@ -19,7 +19,7 @@ - --> <project name="AMQ Broker" default="build"> - <property name="module.depends" value="management/common common"/> + <property name="module.depends" value="management/common common amqp-1-0-common"/> <property name="module.test.depends" value="common/test" /> <property name="module.main" value="org.apache.qpid.server.Main"/> <property name="module.genpom" value="true"/> diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java index 6910247577..8198cec821 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java @@ -89,6 +89,7 @@ import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.RecordDeliveryMethod; import org.apache.qpid.server.subscription.Subscription; import org.apache.qpid.server.subscription.SubscriptionFactoryImpl; +import org.apache.qpid.server.subscription.SubscriptionImpl; import org.apache.qpid.server.txn.AsyncAutoCommitTransaction; import org.apache.qpid.server.txn.LocalTransaction; import org.apache.qpid.server.txn.ServerTransaction; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java index 263b7fe40a..5004d320c2 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java @@ -53,10 +53,16 @@ import java.io.InputStream; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.EnumSet; +import java.util.Formatter; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.Set; +import java.util.logging.ConsoleHandler; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; public class Broker { @@ -159,6 +165,12 @@ public class Broker parsePortList(sslPorts, serverConfig.getSSLPorts()); } + Set<Integer> exclude_1_0 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v1_0)); + if(exclude_1_0.isEmpty()) + { + parsePortList(exclude_1_0, serverConfig.getPortExclude10()); + } + Set<Integer> exclude_0_10 = new HashSet<Integer>(options.getExcludedPorts(ProtocolExclusion.v0_10)); if(exclude_0_10.isEmpty()) { @@ -208,7 +220,8 @@ public class Broker final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, port); final Set<AmqpProtocolVersion> supported = - getSupportedVersions(port, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, serverConfig); + getSupportedVersions(port, exclude_1_0, exclude_0_10, exclude_0_9_1, exclude_0_9, + exclude_0_8, serverConfig); final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); @@ -237,7 +250,8 @@ public class Broker final InetSocketAddress inetSocketAddress = new InetSocketAddress(bindAddress, sslPort); final Set<AmqpProtocolVersion> supported = - getSupportedVersions(sslPort, exclude_0_10, exclude_0_9_1, exclude_0_9, exclude_0_8, serverConfig); + getSupportedVersions(sslPort, exclude_1_0, exclude_0_10, exclude_0_9_1, + exclude_0_9, exclude_0_8, serverConfig); final NetworkTransportConfiguration settings = new ServerNetworkTransportConfiguration(serverConfig, inetSocketAddress, Transport.TCP); @@ -262,13 +276,20 @@ public class Broker } } - private static Set<AmqpProtocolVersion> getSupportedVersions(final int port, final Set<Integer> exclude_0_10, - final Set<Integer> exclude_0_9_1, final Set<Integer> exclude_0_9, - final Set<Integer> exclude_0_8, - final ServerConfiguration serverConfig) + private static Set<AmqpProtocolVersion> getSupportedVersions(final int port, + final Set<Integer> exclude_1_0, + final Set<Integer> exclude_0_10, + final Set<Integer> exclude_0_9_1, + final Set<Integer> exclude_0_9, + final Set<Integer> exclude_0_8, + final ServerConfiguration serverConfig) { final EnumSet<AmqpProtocolVersion> supported = EnumSet.allOf(AmqpProtocolVersion.class); + if(exclude_1_0.contains(port) || !serverConfig.isAmqp10enabled()) + { + supported.remove(AmqpProtocolVersion.v1_0_0); + } if(exclude_0_10.contains(port) || !serverConfig.isAmqp010enabled()) { supported.remove(AmqpProtocolVersion.v0_10); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java index 1f96a24701..d871c724fd 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -47,7 +47,6 @@ public class BrokerOptions private Integer _logWatchFrequency = 0; - public void addPort(final int port) { _ports.add(port); @@ -107,7 +106,6 @@ public class BrokerOptions { _jmxPortConnectorServer = jmxPortConnectorServer; } - public String getQpidHome() { return System.getProperty(QPID_HOME); @@ -163,5 +161,4 @@ public class BrokerOptions { _bundleContext = bundleContext; } - }
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java index 5fcd8a7b52..70fa414e3c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -59,6 +59,12 @@ public class Main .withDescription("SSL port. Overrides any value in the config file") .withLongOpt("sslport").create("s"); + + private static final Option OPTION_EXCLUDE_1_0 = + OptionBuilder.withArgName("port").hasArg() + .withDescription("when listening on the specified port do not accept AMQP1-0 connections. The specified port must be one specified on the command line") + .withLongOpt("exclude-1-0").create(); + private static final Option OPTION_EXCLUDE_0_10 = OptionBuilder.withArgName("port").hasArg() .withDescription("when listening on the specified port do not accept AMQP0-10 connections. The specified port must be one specified on the command line") @@ -116,6 +122,7 @@ public class Main OPTIONS.addOption(OPTION_LOG_WATCH); OPTIONS.addOption(OPTION_PORT); OPTIONS.addOption(OPTION_SSLPORT); + OPTIONS.addOption(OPTION_EXCLUDE_1_0); OPTIONS.addOption(OPTION_EXCLUDE_0_10); OPTIONS.addOption(OPTION_EXCLUDE_0_9_1); OPTIONS.addOption(OPTION_EXCLUDE_0_9); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java index 22d97d36dd..fe6e32173f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/ProtocolExclusion.java @@ -28,7 +28,8 @@ public enum ProtocolExclusion v0_8("exclude-0-8","--exclude-0-8"), v0_9("exclude-0-9", "--exclude-0-9"), v0_9_1("exclude-0-9-1", "--exclude-0-9-1"), - v0_10("exclude-0-10", "--exclude-0-10"); + v0_10("exclude-0-10", "--exclude-0-10"), + v1_0("exclude-1-0", "--exclude-1-0"); private static final Map<String, ProtocolExclusion> MAP = new HashMap<String,ProtocolExclusion>(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java index 5d0546f6a7..46027d02c6 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java @@ -88,6 +88,7 @@ public class ServerConfiguration extends ConfigurationPlugin public static final String MGMT_JMXPORT_CONNECTORSERVER = "management.jmxport.connectorServer"; public static final String STATUS_UPDATES = "status-updates"; public static final String ADVANCED_LOCALE = "advanced.locale"; + public static final String CONNECTOR_AMQP10ENABLED = "connector.amqp10enabled"; public static final String CONNECTOR_AMQP010ENABLED = "connector.amqp010enabled"; public static final String CONNECTOR_AMQP091ENABLED = "connector.amqp091enabled"; public static final String CONNECTOR_AMQP09ENABLED = "connector.amqp09enabled"; @@ -667,6 +668,11 @@ public class ServerConfiguration extends ConfigurationPlugin return getListValue("connector.port", Collections.<Integer>singletonList(DEFAULT_PORT)); } + public List getPortExclude10() + { + return getListValue("connector.non10port"); + } + public List getPortExclude010() { return getListValue("connector.non010port"); @@ -843,6 +849,11 @@ public class ServerConfiguration extends ConfigurationPlugin return getConfig().getString("deadLetterQueueSuffix", AMQQueueFactory.DEFAULT_DLQ_NAME_SUFFIX); } + public boolean isAmqp10enabled() + { + return getConfig().getBoolean(CONNECTOR_AMQP10ENABLED, true); + } + public boolean isAmqp010enabled() { return getConfig().getBoolean(CONNECTOR_AMQP010ENABLED, true); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java index 18a0e4c8bf..6c158de8b5 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/filter/SimpleFilterManager.java @@ -39,6 +39,12 @@ public class SimpleFilterManager implements FilterManager _filters = new ConcurrentLinkedQueue<MessageFilter>(); } + public SimpleFilterManager(JMSSelectorFilter messageFilter) + { + this(); + add(messageFilter); + } + public void add(MessageFilter filter) { _filters.add(filter); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java new file mode 100755 index 0000000000..9cb5904bb3 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/message/MessageMetaData_1_0.java @@ -0,0 +1,522 @@ +/* +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +* +*/ +package org.apache.qpid.server.message; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.qpid.amqp_1_0.codec.ValueHandler; +import org.apache.qpid.amqp_1_0.messaging.SectionDecoder; +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.Symbol; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; +import org.apache.qpid.amqp_1_0.type.messaging.AmqpSequence; +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.Data; +import org.apache.qpid.amqp_1_0.type.messaging.DeliveryAnnotations; +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 org.apache.qpid.server.store.MessageMetaDataType; +import org.apache.qpid.server.store.StorableMessageMetaData; + +public class MessageMetaData_1_0 implements StorableMessageMetaData +{ + // TODO move to somewhere more useful + public static final Symbol JMS_TYPE = Symbol.valueOf("jms-type"); + + + private Header _header; + private Properties _properties; + private Map _deliveryAnnotations; + private Map _messageAnnotations; + private Map _appProperties; + private Map _footer; + + private List<ByteBuffer> _encodedSections = new ArrayList<ByteBuffer>(3); + + private volatile ByteBuffer _encoded; + private MessageHeader_1_0 _messageHeader; + + + + public MessageMetaData_1_0(ByteBuffer[] fragments, SectionDecoder decoder) + { + this(fragments, decoder, new ArrayList<ByteBuffer>(3)); + } + + public MessageMetaData_1_0(ByteBuffer[] fragments, SectionDecoder decoder, List<ByteBuffer> immuatableSections) + { + this(constructSections(fragments, decoder,immuatableSections), immuatableSections); + } + + private MessageMetaData_1_0(List<Section> sections, List<ByteBuffer> encodedSections) + { + _encodedSections = encodedSections; + + Iterator<Section> sectIter = sections.iterator(); + + Section section = sectIter.hasNext() ? sectIter.next() : null; + if(section instanceof Header) + { + _header = (Header) section; + section = sectIter.hasNext() ? sectIter.next() : null; + } + + if(section instanceof DeliveryAnnotations) + { + _deliveryAnnotations = ((DeliveryAnnotations) section).getValue(); + section = sectIter.hasNext() ? sectIter.next() : null; + } + + if(section instanceof MessageAnnotations) + { + _messageAnnotations = ((MessageAnnotations) section).getValue(); + section = sectIter.hasNext() ? sectIter.next() : null; + } + + if(section instanceof Properties) + { + _properties = (Properties) section; + section = sectIter.hasNext() ? sectIter.next() : null; + } + + if(section instanceof ApplicationProperties) + { + _appProperties = ((ApplicationProperties) section).getValue(); + section = sectIter.hasNext() ? sectIter.next() : null; + } + + if(section instanceof Footer) + { + _footer = ((Footer) section).getValue(); + section = sectIter.hasNext() ? sectIter.next() : null; + } + + _messageHeader = new MessageHeader_1_0(); + + } + + private static List<Section> constructSections(final ByteBuffer[] fragments, final SectionDecoder decoder, List<ByteBuffer> encodedSections) + { + List<Section> sections = new ArrayList<Section>(3); + + ByteBuffer src; + if(fragments.length == 1) + { + src = fragments[0].duplicate(); + } + else + { + int size = 0; + for(ByteBuffer buf : fragments) + { + size += buf.remaining(); + } + src = ByteBuffer.allocate(size); + for(ByteBuffer buf : fragments) + { + src.put(buf.duplicate()); + } + src.flip(); + + } + + try + { + int startBarePos = -1; + int lastPos = src.position(); + Section s = decoder.readSection(src); + + + + if(s instanceof Header) + { + sections.add(s); + lastPos = src.position(); + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + + if(s instanceof DeliveryAnnotations) + { + sections.add(s); + lastPos = src.position(); + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + + if(s instanceof MessageAnnotations) + { + sections.add(s); + lastPos = src.position(); + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + + if(s instanceof Properties) + { + sections.add(s); + if(startBarePos == -1) + { + startBarePos = lastPos; + } + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + + if(s instanceof ApplicationProperties) + { + sections.add(s); + if(startBarePos == -1) + { + startBarePos = lastPos; + } + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + + if(s instanceof AmqpValue) + { + if(startBarePos == -1) + { + startBarePos = lastPos; + } + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + else if(s instanceof Data) + { + if(startBarePos == -1) + { + startBarePos = lastPos; + } + do + { + s = src.hasRemaining() ? decoder.readSection(src) : null; + } while(s instanceof Data); + } + else if(s instanceof AmqpSequence) + { + if(startBarePos == -1) + { + startBarePos = lastPos; + } + do + { + s = src.hasRemaining() ? decoder.readSection(src) : null; + } + while(s instanceof AmqpSequence); + } + + if(s instanceof Footer) + { + sections.add(s); + } + + + int pos = 0; + for(ByteBuffer buf : fragments) + { +/* + if(pos < startBarePos) + { + if(pos + buf.remaining() > startBarePos) + { + ByteBuffer dup = buf.duplicate(); + dup.position(dup.position()+startBarePos-pos); + dup.slice(); + encodedSections.add(dup); + } + } + else +*/ + { + encodedSections.add(buf.duplicate()); + } + pos += buf.remaining(); + } + + return sections; + } + catch (AmqpErrorException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + throw new IllegalArgumentException(e); + } + } + + + public MessageMetaDataType getType() + { + return MessageMetaDataType.META_DATA_1_0; + } + + + public int getStorableSize() + { + int size = 0; + + for(ByteBuffer bin : _encodedSections) + { + size += bin.limit(); + } + + return size; + } + + private ByteBuffer encodeAsBuffer() + { + ByteBuffer buf = ByteBuffer.allocate(getStorableSize()); + + for(ByteBuffer bin : _encodedSections) + { + buf.put(bin.duplicate()); + } + + return buf; + } + + public int writeToBuffer(int offsetInMetaData, ByteBuffer dest) + { + ByteBuffer buf = _encoded; + + if(buf == null) + { + buf = encodeAsBuffer(); + _encoded = buf; + } + + buf = buf.duplicate(); + + buf.position(offsetInMetaData); + + if(dest.remaining() < buf.limit()) + { + buf.limit(dest.remaining()); + } + dest.put(buf); + return buf.limit(); + } + + public int getContentSize() + { + ByteBuffer buf = _encoded; + + if(buf == null) + { + buf = encodeAsBuffer(); + _encoded = buf; + } + return buf.remaining(); + } + + public boolean isPersistent() + { + return _header != null && Boolean.TRUE.equals(_header.getDurable()); + } + + public MessageHeader_1_0 getMessageHeader() + { + return _messageHeader; + } + + public static final MessageMetaDataType.Factory<MessageMetaData_1_0> FACTORY = new MetaDataFactory(); + + + private static class MetaDataFactory implements MessageMetaDataType.Factory<MessageMetaData_1_0> + { + private final AMQPDescribedTypeRegistry _typeRegistry = AMQPDescribedTypeRegistry.newInstance(); + + public MessageMetaData_1_0 createMetaData(ByteBuffer buf) + { + ValueHandler valueHandler = new ValueHandler(_typeRegistry); + + ArrayList<Section> sections = new ArrayList<Section>(3); + ArrayList<ByteBuffer> encodedSections = new ArrayList<ByteBuffer>(3); + + while(buf.hasRemaining()) + { + try + { + ByteBuffer encodedBuf = buf.duplicate(); + sections.add((Section) valueHandler.parse(buf)); + encodedBuf.limit(buf.position()); + encodedSections.add(encodedBuf); + + } + catch (AmqpErrorException e) + { + //TODO + throw new RuntimeException(e); + } + + } + + return new MessageMetaData_1_0(sections,encodedSections); + + } + } + + public class MessageHeader_1_0 implements AMQMessageHeader + { + + public String getCorrelationId() + { + if(_properties == null || _properties.getCorrelationId() == null) + { + return null; + } + else + { + return _properties.getMessageId().toString(); + } + } + + public long getExpiration() + { + return 0; //TODO + } + + public String getMessageId() + { + if(_properties == null || _properties.getCorrelationId() == null) + { + return null; + } + else + { + return _properties.getCorrelationId().toString(); + } + } + + public String getMimeType() + { + + if(_properties == null || _properties.getContentType() == null) + { + return null; + } + else + { + return _properties.getContentType().toString(); + } + } + + public String getEncoding() + { + return null; //TODO + } + + public byte getPriority() + { + if(_header == null || _header.getPriority() == null) + { + return 4; //javax.jms.Message.DEFAULT_PRIORITY; + } + else + { + return _header.getPriority().byteValue(); + } + } + + public long getTimestamp() + { + if(_properties == null || _properties.getCreationTime() == null) + { + return 0L; + } + else + { + return _properties.getCreationTime().getTime(); + } + + } + + public String getType() + { + + if(_messageAnnotations == null || _messageAnnotations.get(JMS_TYPE) == null) + { + return null; + } + else + { + return _messageAnnotations.get(JMS_TYPE).toString(); + } + } + + public String getReplyTo() + { + if(_properties == null || _properties.getReplyTo() == null) + { + return null; + } + else + { + return _properties.getReplyTo().toString(); + } + } + + public String getReplyToExchange() + { + return null; //TODO + } + + public String getReplyToRoutingKey() + { + return null; //TODO + } + + public Object getHeader(final String name) + { + return _appProperties == null ? null : _appProperties.get(name); + } + + public boolean containsHeaders(final Set<String> names) + { + if(_appProperties == null) + { + return false; + } + + for(String key : names) + { + if(!_appProperties.containsKey(key)) + { + return false; + } + } + return true; + } + + public boolean containsHeader(final String name) + { + return _appProperties != null && _appProperties.containsKey(name); + } + + public String getSubject() + { + return _properties == null ? null : _properties.getSubject(); + } + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java index 1a055240b9..b750b29952 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java @@ -58,6 +58,7 @@ import org.apache.qpid.server.state.AMQStateManager; import org.apache.qpid.server.stats.StatisticsCounter; import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.subscription.SubscriptionImpl; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.server.virtualhost.VirtualHostRegistry; import org.apache.qpid.transport.Sender; @@ -1455,7 +1456,7 @@ public class AMQProtocolEngine implements ServerProtocolEngine, Managable, AMQPr throws AMQException { registerMessageDelivered(entry.getMessage().getSize()); - _protocolOutputConverter.writeDeliver(entry, _channelId, deliveryTag, sub.getConsumerTag()); + _protocolOutputConverter.writeDeliver(entry, _channelId, deliveryTag, ((SubscriptionImpl)sub).getConsumerTag()); entry.incrementDeliveryCount(); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java index e925d7a1ec..0a71fe257a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AmqpProtocolVersion.java @@ -20,4 +20,4 @@ */ package org.apache.qpid.server.protocol; -public enum AmqpProtocolVersion { v0_8, v0_9, v0_9_1, v0_10 }
\ No newline at end of file +public enum AmqpProtocolVersion { v0_8, v0_9, v0_9_1, v0_10, v1_0_0 } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java index 3b26f05f84..652ffee004 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngine.java @@ -175,6 +175,28 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine (byte) 10 }; + private static final byte[] AMQP_1_0_0_HEADER = + new byte[] { (byte) 'A', + (byte) 'M', + (byte) 'Q', + (byte) 'P', + (byte) 0, + (byte) 1, + (byte) 0, + (byte) 0 + }; + + private static final byte[] AMQP_SASL_1_0_0_HEADER = + new byte[] { (byte) 'A', + (byte) 'M', + (byte) 'Q', + (byte) 'P', + (byte) 3, + (byte) 1, + (byte) 0, + (byte) 0 + }; + public void setNetworkConnection(NetworkConnection networkConnection) { setNetworkConnection(networkConnection, networkConnection.getSender()); @@ -289,8 +311,48 @@ public class MultiVersionProtocolEngine implements ServerProtocolEngine } }; + private DelegateCreator creator_1_0_0 = new DelegateCreator() + { + + public AmqpProtocolVersion getVersion() + { + return AmqpProtocolVersion.v1_0_0; + } + + + public byte[] getHeaderIdentifier() + { + return AMQP_1_0_0_HEADER; + } + + public ServerProtocolEngine getProtocolEngine() + { + return new ProtocolEngine_1_0_0(_appRegistry,_id); + } + }; + + private DelegateCreator creator_1_0_0_SASL = new DelegateCreator() + { + + public AmqpProtocolVersion getVersion() + { + return AmqpProtocolVersion.v1_0_0; + } + + + public byte[] getHeaderIdentifier() + { + return AMQP_SASL_1_0_0_HEADER; + } + + public ServerProtocolEngine getProtocolEngine() + { + return new ProtocolEngine_1_0_0_SASL(_network, _appRegistry, _id); + } + }; + private final DelegateCreator[] _creators = - new DelegateCreator[] { creator_0_8, creator_0_9, creator_0_9_1, creator_0_10 }; + new DelegateCreator[] { creator_0_8, creator_0_9, creator_0_9_1, creator_0_10, creator_1_0_0_SASL, creator_1_0_0 }; private class ClosedDelegateProtocolEngine implements ServerProtocolEngine diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java new file mode 100755 index 0000000000..e6c79a4077 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0.java @@ -0,0 +1,391 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol; + +import org.apache.qpid.amqp_1_0.codec.FrameWriter; +import org.apache.qpid.amqp_1_0.framing.AMQFrame; +import org.apache.qpid.amqp_1_0.framing.FrameHandler; +import org.apache.qpid.amqp_1_0.framing.OversizeFrameException; +import org.apache.qpid.amqp_1_0.transport.*; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.FrameBody; + +import org.apache.qpid.protocol.ServerProtocolEngine; +import org.apache.qpid.server.configuration.*; +import org.apache.qpid.server.protocol.v1_0.Connection_1_0; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.transport.Sender; +import org.apache.qpid.transport.network.NetworkConnection; + +import javax.security.auth.callback.CallbackHandler; +import java.io.PrintWriter; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.security.Principal; +import java.util.UUID; +import java.util.logging.*; +import java.util.concurrent.atomic.AtomicLong; + +public class ProtocolEngine_1_0_0 implements ServerProtocolEngine, FrameOutputHandler +{ + static final AtomicLong _connectionIdSource = new AtomicLong(0L); + + //private NetworkConnection _networkDriver; + private long _readBytes; + private long _writtenBytes; + private final UUID _id; + private final IApplicationRegistry _appRegistry; + private long _createTime = System.currentTimeMillis(); + private ConnectionEndpoint _conn; + private final long _connectionId; + + private static final ByteBuffer HEADER = + ByteBuffer.wrap(new byte[] + { + (byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte) 0, + (byte) 1, + (byte) 0, + (byte) 0 + }); + + private FrameWriter _frameWriter; + private FrameHandler _frameHandler; + private Object _sendLock = new Object(); + private byte _major; + private byte _minor; + private byte _revision; + private NetworkConnection _network; + private Sender<ByteBuffer> _sender; + + + static enum State { + A, + M, + Q, + P, + PROTOCOL, + MAJOR, + MINOR, + REVISION, + FRAME + } + + private State _state = State.A; + + public ProtocolEngine_1_0_0(final IApplicationRegistry appRegistry, long id) + { + _id = appRegistry.getConfigStore().createId(); + _appRegistry = appRegistry; + _connectionId = id; + } + + + public SocketAddress getRemoteAddress() + { + return _network.getRemoteAddress(); + } + + public SocketAddress getLocalAddress() + { + return _network.getLocalAddress(); + } + + public long getReadBytes() + { + return _readBytes; + } + + public long getWrittenBytes() + { + return _writtenBytes; + } + + public void writerIdle() + { + //Todo + } + + public void readerIdle() + { + //Todo + } + + public void setNetworkConnection(final NetworkConnection network, final Sender<ByteBuffer> sender) + { + _network = network; + _sender = sender; + + Container container = new Container(); + + _conn = new ConnectionEndpoint(container,asCallbackHandlerSource(_appRegistry.getAuthenticationManager())); + _conn.setConnectionEventListener(new Connection_1_0(_appRegistry)); + _conn.setFrameOutputHandler(this); + _conn.setRemoteAddress(_network.getRemoteAddress()); + + _frameWriter = new FrameWriter(_conn.getDescribedTypeRegistry()); + _frameHandler = new FrameHandler(_conn); + + _sender.send(HEADER.duplicate()); + _sender.flush(); + } + + private CallbackHandlerSource asCallbackHandlerSource(final AuthenticationManager authenticationManager) + { + return new CallbackHandlerSource() + { + @Override + public CallbackHandler getHandler(String mechanism) + { + return authenticationManager.getHandler(mechanism); + } + }; + } + + public String getAddress() + { + return getRemoteAddress().toString(); + } + + + public ConfigStore getConfigStore() + { + return _appRegistry.getConfigStore(); + } + + public UUID getId() + { + return _id; + } + + public ConnectionConfigType getConfigType() + { + return ConnectionConfigType.getInstance(); + } + + public boolean isDurable() + { + return false; + } + + public synchronized void received(ByteBuffer msg) + { + if(RAW_LOGGER.isLoggable(Level.FINE)) + { + ByteBuffer dup = msg.duplicate(); + byte[] data = new byte[dup.remaining()]; + dup.get(data); + Binary bin = new Binary(data); + RAW_LOGGER.fine("RECV[" + getRemoteAddress() + "] : " + bin.toString()); + } + _readBytes += msg.remaining(); + switch(_state) + { + case A: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + break; + } + case M: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.M; + break; + } + + case Q: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.Q; + break; + } + case P: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.P; + break; + } + case PROTOCOL: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.PROTOCOL; + break; + } + case MAJOR: + if(msg.hasRemaining()) + { + _major = msg.get(); + } + else + { + _state = State.MAJOR; + break; + } + case MINOR: + if(msg.hasRemaining()) + { + _minor = msg.get(); + } + else + { + _state = State.MINOR; + break; + } + case REVISION: + if(msg.hasRemaining()) + { + _revision = msg.get(); + + _state = State.FRAME; + } + else + { + _state = State.REVISION; + break; + } + case FRAME: + if(msg.hasRemaining()) + { + _frameHandler.parse(msg); + } + } + + } + + public void exception(Throwable t) + { + t.printStackTrace(); + } + + public void closed() + { + _conn.inputClosed(); + if(_conn != null && _conn.getConnectionEventListener() != null) + { + ((Connection_1_0)_conn.getConnectionEventListener()).closed(); + } + + } + + public long getCreateTime() + { + return _createTime; + } + + + public boolean canSend() + { + return true; + } + + public void send(final AMQFrame amqFrame) + { + send(amqFrame, null); + } + + private final Logger FRAME_LOGGER = Logger.getLogger("FRM"); + private final Logger RAW_LOGGER = Logger.getLogger("RAW"); + + + public void send(final AMQFrame amqFrame, ByteBuffer buf) + { + synchronized(_sendLock) + { + + if(FRAME_LOGGER.isLoggable(Level.FINE)) + { + FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody()); + } + + + _frameWriter.setValue(amqFrame); + + + + ByteBuffer dup = ByteBuffer.allocate(_conn.getMaxFrameSize()); + + int size = _frameWriter.writeToBuffer(dup); + if(size > _conn.getMaxFrameSize()) + { + throw new OversizeFrameException(amqFrame,size); + } + + dup.flip(); + _writtenBytes += dup.limit(); + + if(RAW_LOGGER.isLoggable(Level.FINE)) + { + ByteBuffer dup2 = dup.duplicate(); + byte[] data = new byte[dup2.remaining()]; + dup2.get(data); + Binary bin = new Binary(data); + RAW_LOGGER.fine("SEND[" + getRemoteAddress() + "] : " + bin.toString()); + } + + + _sender.send(dup); + _sender.flush(); + + } + } + + public void send(short channel, FrameBody body) + { + AMQFrame frame = AMQFrame.createAMQFrame(channel, body); + send(frame); + + } + + public void close() + { + //TODO + } + + public long getConnectionId() + { + return _connectionId; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java new file mode 100644 index 0000000000..e4487e00f9 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/ProtocolEngine_1_0_0_SASL.java @@ -0,0 +1,453 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol; + +import org.apache.qpid.amqp_1_0.codec.FrameWriter; +import org.apache.qpid.amqp_1_0.codec.ProtocolHandler; +import org.apache.qpid.amqp_1_0.framing.AMQFrame; +import org.apache.qpid.amqp_1_0.framing.FrameHandler; +import org.apache.qpid.amqp_1_0.framing.OversizeFrameException; +import org.apache.qpid.amqp_1_0.framing.SASLFrameHandler; +import org.apache.qpid.amqp_1_0.transport.CallbackHandlerSource; +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.FrameOutputHandler; +import org.apache.qpid.amqp_1_0.type.Binary; +import org.apache.qpid.amqp_1_0.type.FrameBody; + +import org.apache.qpid.protocol.ServerProtocolEngine; +import org.apache.qpid.server.configuration.ConfigStore; +import org.apache.qpid.server.configuration.ConnectionConfigType; +import org.apache.qpid.server.protocol.v1_0.Connection_1_0; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.security.auth.manager.AuthenticationManager; +import org.apache.qpid.transport.Sender; +import org.apache.qpid.transport.network.NetworkConnection; + +import javax.security.auth.callback.CallbackHandler; +import java.io.PrintWriter; +import java.net.SocketAddress; +import java.nio.ByteBuffer; +import java.security.Principal; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOutputHandler +{ + private long _readBytes; + private long _writtenBytes; + private final UUID _id; + private final IApplicationRegistry _appRegistry; + private long _createTime = System.currentTimeMillis(); + private ConnectionEndpoint _conn; + private long _connectionId; + + private static final ByteBuffer HEADER = + ByteBuffer.wrap(new byte[] + { + (byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte) 3, + (byte) 1, + (byte) 0, + (byte) 0 + }); + + private static final ByteBuffer PROTOCOL_HEADER = + ByteBuffer.wrap(new byte[] + { + (byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte) 0, + (byte) 1, + (byte) 0, + (byte) 0 + }); + + + private FrameWriter _frameWriter; + private ProtocolHandler _frameHandler; + private ByteBuffer _buf = ByteBuffer.allocate(1024 * 1024); + private Object _sendLock = new Object(); + private byte _major; + private byte _minor; + private byte _revision; + private PrintWriter _out; + private NetworkConnection _network; + private Sender<ByteBuffer> _sender; + + + static enum State { + A, + M, + Q, + P, + PROTOCOL, + MAJOR, + MINOR, + REVISION, + FRAME + } + + private State _state = State.A; + + + public ProtocolEngine_1_0_0_SASL(final NetworkConnection networkDriver, final IApplicationRegistry appRegistry, + long id) + { + _id = appRegistry.getConfigStore().createId(); + _connectionId = id; + _appRegistry = appRegistry; + + if(networkDriver != null) + { + setNetworkConnection(networkDriver, networkDriver.getSender()); + } + } + + + public SocketAddress getRemoteAddress() + { + return _network.getRemoteAddress(); + } + + public SocketAddress getLocalAddress() + { + return _network.getLocalAddress(); + } + + public long getReadBytes() + { + return _readBytes; + } + + public long getWrittenBytes() + { + return _writtenBytes; + } + + public void writerIdle() + { + //Todo + } + + public void readerIdle() + { + //Todo + } + + public void setNetworkConnection(final NetworkConnection network, final Sender<ByteBuffer> sender) + { + _network = network; + _sender = sender; + + Container container = new Container(); + + _conn = new ConnectionEndpoint(container, asCallbackHandlerSource(ApplicationRegistry.getInstance() + .getAuthenticationManager())); + _conn.setConnectionEventListener(new Connection_1_0(_appRegistry)); + _conn.setRemoteAddress(getRemoteAddress()); + + + _conn.setFrameOutputHandler(this); + _conn.setSaslFrameOutput(this); + + _conn.setOnSaslComplete(new Runnable() + { + + + public void run() + { + if(_conn.isAuthenticated()) + { + _sender.send(PROTOCOL_HEADER.duplicate()); + _sender.flush(); + } + else + { + _network.close(); + } + } + }); + _frameWriter = new FrameWriter(_conn.getDescribedTypeRegistry()); + _frameHandler = new SASLFrameHandler(_conn); + + _sender.send(HEADER.duplicate()); + _sender.flush(); + + _conn.initiateSASL(); + + + } + + private CallbackHandlerSource asCallbackHandlerSource(final AuthenticationManager authenticationManager) + { + return new CallbackHandlerSource() + { + @Override + public CallbackHandler getHandler(String mechanism) + { + return authenticationManager.getHandler(mechanism); + } + }; + } + + public String getAddress() + { + return getRemoteAddress().toString(); + } + + + public ConfigStore getConfigStore() + { + return _appRegistry.getConfigStore(); + } + + public UUID getId() + { + return _id; + } + + public ConnectionConfigType getConfigType() + { + return ConnectionConfigType.getInstance(); + } + + public boolean isDurable() + { + return false; + } + + private final Logger RAW_LOGGER = Logger.getLogger("RAW"); + + + public synchronized void received(ByteBuffer msg) + { + if(RAW_LOGGER.isLoggable(Level.FINE)) + { + ByteBuffer dup = msg.duplicate(); + byte[] data = new byte[dup.remaining()]; + dup.get(data); + Binary bin = new Binary(data); + RAW_LOGGER.fine("RECV[" + getRemoteAddress() + "] : " + bin.toString()); + } + _readBytes += msg.remaining(); + switch(_state) + { + case A: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + break; + } + case M: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.M; + break; + } + + case Q: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.Q; + break; + } + case P: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.P; + break; + } + case PROTOCOL: + if(msg.hasRemaining()) + { + msg.get(); + } + else + { + _state = State.PROTOCOL; + break; + } + case MAJOR: + if(msg.hasRemaining()) + { + _major = msg.get(); + } + else + { + _state = State.MAJOR; + break; + } + case MINOR: + if(msg.hasRemaining()) + { + _minor = msg.get(); + } + else + { + _state = State.MINOR; + break; + } + case REVISION: + if(msg.hasRemaining()) + { + _revision = msg.get(); + + _state = State.FRAME; + } + else + { + _state = State.REVISION; + break; + } + case FRAME: + if(msg.hasRemaining()) + { + _frameHandler = _frameHandler.parse(msg); + } + } + + } + + public void exception(Throwable t) + { + t.printStackTrace(); + } + + public void closed() + { + // todo + _conn.inputClosed(); + if(_conn != null && _conn.getConnectionEventListener() != null) + { + ((Connection_1_0)_conn.getConnectionEventListener()).closed(); + } + + } + + public long getCreateTime() + { + return _createTime; + } + + + public boolean canSend() + { + return true; + } + + public void send(final AMQFrame amqFrame) + { + send(amqFrame, null); + } + + private static final Logger FRAME_LOGGER = Logger.getLogger("FRM"); + + + public void send(final AMQFrame amqFrame, ByteBuffer buf) + { + + synchronized(_sendLock) + { + + if(FRAME_LOGGER.isLoggable(Level.FINE)) + { + FRAME_LOGGER.fine("SEND[" + getRemoteAddress() + "|" + amqFrame.getChannel() + "] : " + amqFrame.getFrameBody()); + } + + + _frameWriter.setValue(amqFrame); + + + + ByteBuffer dup = ByteBuffer.allocate(_conn.getMaxFrameSize()); + + int size = _frameWriter.writeToBuffer(dup); + if(size > _conn.getMaxFrameSize()) + { + throw new OversizeFrameException(amqFrame,size); + } + + dup.flip(); + _writtenBytes += dup.limit(); + + if(RAW_LOGGER.isLoggable(Level.FINE)) + { + ByteBuffer dup2 = dup.duplicate(); + byte[] data = new byte[dup2.remaining()]; + dup2.get(data); + Binary bin = new Binary(data); + RAW_LOGGER.fine("SEND[" + getRemoteAddress() + "] : " + bin.toString()); + } + + + _sender.send(dup); + _sender.flush(); + + + } + } + + public void send(short channel, FrameBody body) + { + AMQFrame frame = AMQFrame.createAMQFrame(channel, body); + send(frame); + + } + + public void close() + { + _sender.close(); + } + + public void setLogOutput(final PrintWriter out) + { + _out = out; + } + + public long getConnectionId() + { + return _connectionId; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java new file mode 100644 index 0000000000..318a240b27 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Connection_1_0.java @@ -0,0 +1,98 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +import org.apache.qpid.amqp_1_0.transport.ConnectionEventListener; +import org.apache.qpid.amqp_1_0.transport.SessionEndpoint; + +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.virtualhost.VirtualHost; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class Connection_1_0 implements ConnectionEventListener +{ + + private IApplicationRegistry _appRegistry; + private VirtualHost _vhost; + + + public static interface Task + { + public void doTask(Connection_1_0 connection); + } + + + private List<Task> _closeTasks = + Collections.synchronizedList(new ArrayList<Task>()); + + + + public Connection_1_0(IApplicationRegistry appRegistry) + { + _appRegistry = appRegistry; + _vhost = _appRegistry.getVirtualHostRegistry().getDefaultVirtualHost(); + } + + public void remoteSessionCreation(SessionEndpoint endpoint) + { + Session_1_0 session = new Session_1_0(_vhost, _appRegistry, this); + endpoint.setSessionEventListener(session); + } + + + void removeConnectionCloseTask(final Task task) + { + _closeTasks.remove( task ); + } + + void addConnectionCloseTask(final Task task) + { + _closeTasks.add( task ); + } + + public void closeReceived() + { + List<Task> taskCopy; + synchronized (_closeTasks) + { + taskCopy = new ArrayList<Task>(_closeTasks); + } + for(Task task : taskCopy) + { + task.doTask(this); + } + synchronized (_closeTasks) + { + _closeTasks.clear(); + } + + } + + public void closed() + { + closeReceived(); + } + + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Destination.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Destination.java new file mode 100644 index 0000000000..d45758391c --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/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.server.protocol.v1_0; + + +public interface Destination +{ + + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.java new file mode 100644 index 0000000000..ba1a1ca45c --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ExchangeDestination.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.server.protocol.v1_0; + +import java.util.List; +import org.apache.qpid.AMQException; +import org.apache.qpid.amqp_1_0.type.Outcome; +import org.apache.qpid.amqp_1_0.type.messaging.Accepted; +import org.apache.qpid.amqp_1_0.type.messaging.TerminusDurability; +import org.apache.qpid.amqp_1_0.type.messaging.TerminusExpiryPolicy; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.BaseQueue; +import org.apache.qpid.server.txn.ServerTransaction; + +public class ExchangeDestination implements ReceivingDestination, SendingDestination +{ + private static final Accepted ACCEPTED = new Accepted(); + private static final Outcome[] OUTCOMES = { ACCEPTED }; + + private Exchange _exchange; + private TerminusDurability _durability; + private TerminusExpiryPolicy _expiryPolicy; + + public ExchangeDestination(Exchange exchange, TerminusDurability durable, TerminusExpiryPolicy expiryPolicy) + { + _exchange = exchange; + _durability = durable; + _expiryPolicy = expiryPolicy; + } + + public Outcome[] getOutcomes() + { + return OUTCOMES; + } + + public Outcome send(final Message_1_0 message, ServerTransaction txn) + { + final List<? extends BaseQueue> queues = _exchange.route(message); + + txn.enqueue(queues,message, new ServerTransaction.Action() + { + + BaseQueue[] _queues = queues.toArray(new BaseQueue[queues.size()]); + + public void postCommit() + { + for(int i = 0; i < _queues.length; i++) + { + try + { + _queues[i].enqueue(message); + } + catch (AMQException e) + { + // TODO + throw new RuntimeException(e); + } + } + } + + public void onRollback() + { + // NO-OP + } + }, System.currentTimeMillis()); + + return ACCEPTED; + } + + TerminusDurability getDurability() + { + return _durability; + } + + TerminusExpiryPolicy getExpiryPolicy() + { + return _expiryPolicy; + } + + public int getCredit() + { + // TODO - fix + return 20000; + } + + public Exchange getExchange() + { + return _exchange; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java new file mode 100644 index 0000000000..42eea05d37 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/LinkRegistry.java @@ -0,0 +1,59 @@ +package org.apache.qpid.server.protocol.v1_0; + +import java.util.HashMap; +import java.util.Map; + +public class LinkRegistry +{ + private final Map<String, SendingLink_1_0> _sendingLinks = new HashMap<String, SendingLink_1_0>(); + private final Map<String, ReceivingLink_1_0> _receivingLinks = new HashMap<String, ReceivingLink_1_0>(); + + public synchronized SendingLink_1_0 getDurableSendingLink(String name) + { + return _sendingLinks.get(name); + } + + public synchronized boolean registerSendingLink(String name, SendingLink_1_0 link) + { + if(_sendingLinks.containsKey(name)) + { + return false; + } + else + { + _sendingLinks.put(name, link); + return true; + } + } + + public synchronized boolean unregisterSendingLink(String name) + { + if(!_sendingLinks.containsKey(name)) + { + return false; + } + else + { + _sendingLinks.remove(name); + return true; + } + } + + public synchronized ReceivingLink_1_0 getDurableReceivingLink(String name) + { + return _receivingLinks.get(name); + } + + public synchronized boolean registerReceivingLink(String name, ReceivingLink_1_0 link) + { + if(_receivingLinks.containsKey(name)) + { + return false; + } + else + { + _receivingLinks.put(name, link); + return true; + } + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.java new file mode 100644 index 0000000000..db81d3b205 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Link_1_0.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.server.protocol.v1_0; + +public interface Link_1_0 +{ + void start(); +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.java new file mode 100644 index 0000000000..140a815f57 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Message_1_0.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.server.protocol.v1_0; + + +import java.lang.ref.WeakReference; +import java.nio.ByteBuffer; +import java.util.List; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.SessionConfig; +import org.apache.qpid.server.message.InboundMessage; +import org.apache.qpid.server.message.MessageMetaData_1_0; +import org.apache.qpid.server.message.MessageReference; +import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.store.StoredMessage; + +public class Message_1_0 implements ServerMessage, InboundMessage +{ + private final StoredMessage<MessageMetaData_1_0> _storedMessage; + private List<ByteBuffer> _fragments; + private WeakReference<Session_1_0> _session; + + + public Message_1_0(final StoredMessage<MessageMetaData_1_0> storedMessage, + final List<ByteBuffer> fragments, + final Session_1_0 session) + { + _storedMessage = storedMessage; + _fragments = fragments; + _session = new WeakReference<Session_1_0>(session); + } + + public String getRoutingKey() + { + Object routingKey = getMessageHeader().getHeader("routing-key"); + if(routingKey != null) + { + return routingKey.toString(); + } + else + { + return getMessageHeader().getSubject(); + } + } + + public AMQShortString getRoutingKeyShortString() + { + return AMQShortString.valueOf(getRoutingKey()); + } + + private MessageMetaData_1_0 getMessageMetaData() + { + return _storedMessage.getMetaData(); + } + + public MessageMetaData_1_0.MessageHeader_1_0 getMessageHeader() + { + return getMessageMetaData().getMessageHeader(); + } + + public StoredMessage getStoredMessage() + { + return _storedMessage; + } + + public boolean isPersistent() + { + return getMessageMetaData().isPersistent(); + } + + public boolean isRedelivered() + { + // TODO + return false; + } + + public long getSize() + { + // TODO + return 0l; + } + + public boolean isImmediate() + { + return false; + } + + public long getExpiration() + { + return getMessageHeader().getExpiration(); + } + + public MessageReference<Message_1_0> newReference() + { + return new Reference(this); + } + + public long getMessageNumber() + { + return _storedMessage.getMessageNumber(); + } + + public long getArrivalTime() + { + return 0; //TODO + } + + public int getContent(final ByteBuffer buf, final int offset) + { + return _storedMessage.getContent(offset, buf); + } + + public ByteBuffer getContent(int offset, int size) + { + ByteBuffer buf = ByteBuffer.allocate(size); + buf.limit(getContent(buf, offset)); + + return buf; + } + + public SessionConfig getSessionConfig() + { + return null; //TODO + } + + public List<ByteBuffer> getFragments() + { + return _fragments; + } + + public Session_1_0 getSession() + { + return _session.get(); + } + + public static class Reference extends MessageReference<Message_1_0> + { + public Reference(Message_1_0 message) + { + super(message); + } + + protected void onReference(Message_1_0 message) + { + + } + + protected void onRelease(Message_1_0 message) + { + + } + +} +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/QueueDestination.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/QueueDestination.java new file mode 100644 index 0000000000..af3f0b7872 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/QueueDestination.java @@ -0,0 +1,100 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +import org.apache.qpid.amqp_1_0.type.Outcome; +import org.apache.qpid.amqp_1_0.type.messaging.Accepted; + +import org.apache.qpid.AMQException; +import org.apache.qpid.server.queue.AMQQueue; + +import org.apache.qpid.server.txn.ServerTransaction; + +import java.util.Arrays; + +public class QueueDestination implements SendingDestination, ReceivingDestination +{ + private static final Accepted ACCEPTED = new Accepted(); + private static final Outcome[] OUTCOMES = new Outcome[] { ACCEPTED }; + + + private AMQQueue _queue; + + public QueueDestination(AMQQueue queue) + { + _queue = queue; + } + + public Outcome[] getOutcomes() + { + return OUTCOMES; + } + + public Outcome send(final Message_1_0 message, ServerTransaction txn) + { + + try + { + txn.enqueue(_queue,message, new ServerTransaction.Action() + { + + + public void postCommit() + { + try + { + + _queue.enqueue(message); + } + catch (Exception e) + { + // TODO + throw new RuntimeException(e); + } + + } + + public void onRollback() + { + // NO-OP + } + }); + } + catch(Exception e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + return ACCEPTED; + } + + public int getCredit() + { + // TODO - fix + return 100; + } + + public AMQQueue getQueue() + { + return _queue; + } + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingDestination.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingDestination.java new file mode 100644 index 0000000000..4ae0596e25 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingDestination.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.server.protocol.v1_0; + +import org.apache.qpid.amqp_1_0.type.Outcome; + +import org.apache.qpid.server.txn.ServerTransaction; + +public interface ReceivingDestination extends Destination +{ + + Outcome[] getOutcomes(); + + Outcome send(Message_1_0 message, ServerTransaction txn); + + int getCredit(); +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java new file mode 100644 index 0000000000..6da5081185 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLinkAttachment.java @@ -0,0 +1,51 @@ +package org.apache.qpid.server.protocol.v1_0; + +import org.apache.qpid.amqp_1_0.transport.DeliveryStateHandler; +import org.apache.qpid.amqp_1_0.transport.ReceivingLinkEndpoint; +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.Source; +import org.apache.qpid.amqp_1_0.type.Target; + +public class ReceivingLinkAttachment +{ + private final Session_1_0 _session; + private final ReceivingLinkEndpoint _endpoint; + + public ReceivingLinkAttachment(final Session_1_0 session, final ReceivingLinkEndpoint endpoint) + { + _session = session; + _endpoint = endpoint; + } + + public Session_1_0 getSession() + { + return _session; + } + + public ReceivingLinkEndpoint getEndpoint() + { + return _endpoint; + } + + public Source getSource() + { + return getEndpoint().getSource(); + } + + public void setDeliveryStateHandler(final DeliveryStateHandler handler) + { + getEndpoint().setDeliveryStateHandler(handler); + } + + public void updateDisposition(final Binary deliveryTag, final DeliveryState state, final boolean settled) + { + getEndpoint().updateDisposition(deliveryTag, state, settled); + } + + public Target getTarget() + { + return getEndpoint().getTarget(); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java new file mode 100644 index 0000000000..e097dd5c83 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/ReceivingLink_1_0.java @@ -0,0 +1,305 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.qpid.amqp_1_0.messaging.SectionDecoderImpl; +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.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.UnsignedInteger; +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.transaction.TransactionalState; +import org.apache.qpid.amqp_1_0.type.transport.Detach; +import org.apache.qpid.amqp_1_0.type.transport.ReceiverSettleMode; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; +import org.apache.qpid.server.message.MessageMetaData_1_0; +import org.apache.qpid.server.store.StoredMessage; +import org.apache.qpid.server.txn.AutoCommitTransaction; +import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class ReceivingLink_1_0 implements ReceivingLinkListener, Link_1_0, DeliveryStateHandler +{ + private VirtualHost _vhost; + + private ReceivingDestination _destination; + private SectionDecoderImpl _sectionDecoder; + private volatile ReceivingLinkAttachment _attachment; + + + private ArrayList<Transfer> _incompleteMessage; + private TerminusDurability _durability; + + private Map<Binary, Outcome> _unsettledMap = Collections.synchronizedMap(new HashMap<Binary, Outcome>()); + private boolean _resumedMessage; + private Binary _messageDeliveryTag; + private ReceiverSettleMode _receivingSettlementMode; + + + public ReceivingLink_1_0(ReceivingLinkAttachment receivingLinkAttachment, VirtualHost vhost, + ReceivingDestination destination) + { + _vhost = vhost; + _destination = destination; + _attachment = receivingLinkAttachment; + receivingLinkAttachment.setDeliveryStateHandler(this); + + _durability = ((Target)receivingLinkAttachment.getTarget()).getDurable(); + + _sectionDecoder = new SectionDecoderImpl(receivingLinkAttachment.getEndpoint().getSession().getConnection().getDescribedTypeRegistry()); + + + } + + public void messageTransfer(Transfer xfr) + { + // TODO - cope with fragmented messages + + List<ByteBuffer> fragments = null; + + + + if(Boolean.TRUE.equals(xfr.getMore()) && _incompleteMessage == null) + { + _incompleteMessage = new ArrayList<Transfer>(); + _incompleteMessage.add(xfr); + _resumedMessage = Boolean.TRUE.equals(xfr.getResume()); + _messageDeliveryTag = xfr.getDeliveryTag(); + return; + } + else if(_incompleteMessage != null) + { + _incompleteMessage.add(xfr); + + if(Boolean.TRUE.equals(xfr.getMore())) + { + return; + } + + fragments = new ArrayList<ByteBuffer>(_incompleteMessage.size()); + for(Transfer t : _incompleteMessage) + { + fragments.add(t.getPayload()); + } + _incompleteMessage=null; + + } + else + { + _resumedMessage = Boolean.TRUE.equals(xfr.getResume()); + _messageDeliveryTag = xfr.getDeliveryTag(); + fragments = Collections.singletonList(xfr.getPayload()); + } + + if(_resumedMessage) + { + if(_unsettledMap.containsKey(_messageDeliveryTag)) + { + Outcome outcome = _unsettledMap.get(_messageDeliveryTag); + boolean settled = ReceiverSettleMode.FIRST.equals(getReceivingSettlementMode()); + getEndpoint().updateDisposition(_messageDeliveryTag, (DeliveryState) outcome, settled); + if(settled) + { + _unsettledMap.remove(_messageDeliveryTag); + } + } + else + { + System.err.println("UNEXPECTED!!"); + System.err.println("Delivery Tag: " + _messageDeliveryTag); + System.err.println("_unsettledMap: " + _unsettledMap); + + } + } + else + { + MessageMetaData_1_0 mmd = null; + List<ByteBuffer> immutableSections = new ArrayList<ByteBuffer>(3); + mmd = new MessageMetaData_1_0(fragments.toArray(new ByteBuffer[fragments.size()]), + _sectionDecoder, + immutableSections); + + StoredMessage<MessageMetaData_1_0> storedMessage = _vhost.getMessageStore().addMessage(mmd); + + boolean skipping = true; + int offset = 0; + + for(ByteBuffer bareMessageBuf : immutableSections) + { + storedMessage.addContent(offset, bareMessageBuf.duplicate()); + offset += bareMessageBuf.remaining(); + } + + storedMessage.flushToStore(); + + Message_1_0 message = new Message_1_0(storedMessage, fragments, getSession()); + + + Binary transactionId = null; + org.apache.qpid.amqp_1_0.type.DeliveryState xfrState = xfr.getState(); + if(xfrState != null) + { + if(xfrState instanceof TransactionalState) + { + transactionId = ((TransactionalState)xfrState).getTxnId(); + } + } + + ServerTransaction transaction = null; + if(transactionId != null) + { + transaction = getSession().getTransaction(transactionId); + } + else + { + Session_1_0 session = getSession(); + transaction = session != null ? session.getTransaction(null) : new AutoCommitTransaction(_vhost.getMessageStore()); + } + + Outcome outcome = _destination.send(message, transaction); + + DeliveryState resultantState; + + if(transactionId == null) + { + resultantState = (DeliveryState) outcome; + } + else + { + TransactionalState transactionalState = new TransactionalState(); + transactionalState.setOutcome(outcome); + transactionalState.setTxnId(transactionId); + resultantState = transactionalState; + + } + + + boolean settled = transaction instanceof AutoCommitTransaction && ReceiverSettleMode.FIRST.equals(getReceivingSettlementMode()); + + final Binary deliveryTag = xfr.getDeliveryTag(); + + if(!settled) + { + _unsettledMap.put(deliveryTag, outcome); + } + + getEndpoint().updateDisposition(deliveryTag, resultantState, settled); + + if(!(transaction instanceof AutoCommitTransaction)) + { + ServerTransaction.Action a; + transaction.addPostTransactionAction(new ServerTransaction.Action() + { + public void postCommit() + { + getEndpoint().updateDisposition(deliveryTag, null, true); + } + + public void onRollback() + { + getEndpoint().updateDisposition(deliveryTag, null, true); + } + }); + } + } + } + + private ReceiverSettleMode getReceivingSettlementMode() + { + return _receivingSettlementMode; + } + + public void remoteDetached(LinkEndpoint endpoint, Detach detach) + { + //TODO + // if not durable or close + if(!TerminusDurability.UNSETTLED_STATE.equals(_durability) || + (detach != null && Boolean.TRUE.equals(detach.getClosed()))) + { + endpoint.close(); + } + else if(detach == null || detach.getError() != null) + { + _attachment = null; + } + } + + public void start() + { + getEndpoint().setLinkCredit(UnsignedInteger.valueOf(_destination.getCredit())); + getEndpoint().setCreditWindow(); + } + + public ReceivingLinkEndpoint getEndpoint() + { + return _attachment.getEndpoint(); + } + + + public Session_1_0 getSession() + { + ReceivingLinkAttachment attachment = _attachment; + return attachment == null ? null : attachment.getSession(); + } + + public void handle(Binary deliveryTag, DeliveryState state, Boolean settled) + { + if(Boolean.TRUE.equals(settled)) + { + _unsettledMap.remove(deliveryTag); + } + } + + public void setLinkAttachment(ReceivingLinkAttachment linkAttachment) + { + _attachment = linkAttachment; + _receivingSettlementMode = linkAttachment.getEndpoint().getReceivingSettlementMode(); + ReceivingLinkEndpoint endpoint = linkAttachment.getEndpoint(); + Map initialUnsettledMap = endpoint.getInitialUnsettledMap(); + + Map<Binary, Outcome> unsettledCopy = new HashMap<Binary, Outcome>(_unsettledMap); + for(Map.Entry<Binary, Outcome> entry : unsettledCopy.entrySet()) + { + Binary deliveryTag = entry.getKey(); + if(!initialUnsettledMap.containsKey(deliveryTag)) + { + _unsettledMap.remove(deliveryTag); + } + } + + } + + public Map getUnsettledOutcomeMap() + { + return _unsettledMap; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingDestination.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingDestination.java new file mode 100644 index 0000000000..6d601c9dda --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingDestination.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.server.protocol.v1_0; + + +public interface SendingDestination extends Destination +{ + +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java new file mode 100644 index 0000000000..9d7af24135 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLinkAttachment.java @@ -0,0 +1,44 @@ +package org.apache.qpid.server.protocol.v1_0; + +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.Source; + +public class SendingLinkAttachment +{ + private final Session_1_0 _session; + private final SendingLinkEndpoint _endpoint; + + public SendingLinkAttachment(final Session_1_0 session, final SendingLinkEndpoint endpoint) + { + _session = session; + _endpoint = endpoint; + } + + public Session_1_0 getSession() + { + return _session; + } + + public SendingLinkEndpoint getEndpoint() + { + return _endpoint; + } + + public Source getSource() + { + return getEndpoint().getSource(); + } + + public void setDeliveryStateHandler(final DeliveryStateHandler handler) + { + getEndpoint().setDeliveryStateHandler(handler); + } + + public void updateDisposition(final Binary deliveryTag, final DeliveryState state, final boolean settled) + { + getEndpoint().updateDisposition(deliveryTag, state, settled); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java new file mode 100644 index 0000000000..edd3bb6248 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/SendingLink_1_0.java @@ -0,0 +1,646 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.qpid.AMQException; +import org.apache.qpid.AMQInternalException; +import org.apache.qpid.AMQSecurityException; +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.SendingLinkEndpoint; +import org.apache.qpid.amqp_1_0.transport.SendingLinkListener; +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.DeliveryState; +import org.apache.qpid.amqp_1_0.type.Outcome; +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.Accepted; +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 org.apache.qpid.amqp_1_0.type.messaging.NoLocalFilter; +import org.apache.qpid.amqp_1_0.type.messaging.Released; +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.TerminusDurability; +import org.apache.qpid.amqp_1_0.type.transport.AmqpError; +import org.apache.qpid.amqp_1_0.type.transport.Detach; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; +import org.apache.qpid.filter.SelectorParsingException; +import org.apache.qpid.filter.selector.ParseException; +import org.apache.qpid.server.binding.Binding; +import org.apache.qpid.server.exchange.DirectExchange; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.exchange.TopicExchange; +import org.apache.qpid.server.filter.JMSSelectorFilter; +import org.apache.qpid.server.filter.SimpleFilterManager; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.txn.AutoCommitTransaction; +import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class SendingLink_1_0 implements SendingLinkListener, Link_1_0, DeliveryStateHandler +{ + private VirtualHost _vhost; + private SendingDestination _destination; + + private Subscription_1_0 _subscription; + private boolean _draining; + private final Map<Binary, QueueEntry> _unsettledMap = + new HashMap<Binary, QueueEntry>(); + + private final ConcurrentHashMap<Binary, UnsettledAction> _unsettledActionMap = + new ConcurrentHashMap<Binary, UnsettledAction>(); + private volatile SendingLinkAttachment _linkAttachment; + private TerminusDurability _durability; + private List<QueueEntry> _resumeFullTransfers = new ArrayList<QueueEntry>(); + private List<Binary> _resumeAcceptedTransfers = new ArrayList<Binary>(); + private Runnable _closeAction; + + public SendingLink_1_0(final SendingLinkAttachment linkAttachment, + final VirtualHost vhost, + final SendingDestination destination) + throws AmqpErrorException + { + _vhost = vhost; + _destination = destination; + _linkAttachment = linkAttachment; + final Source source = (Source) linkAttachment.getSource(); + _durability = source.getDurable(); + linkAttachment.setDeliveryStateHandler(this); + QueueDestination qd = null; + AMQQueue queue = null; + + + + boolean noLocal = false; + JMSSelectorFilter messageFilter = null; + + if(destination instanceof QueueDestination) + { + queue = ((QueueDestination) _destination).getQueue(); + if(queue.getArguments() != null && queue.getArguments().containsKey("topic")) + { + source.setDistributionMode(StdDistMode.COPY); + } + qd = (QueueDestination) destination; + + Map<Symbol,Filter> filters = source.getFilter(); + + Map<Symbol,Filter> actualFilters = new HashMap<Symbol,Filter>(); + + if(filters != null) + { + for(Map.Entry<Symbol,Filter> entry : filters.entrySet()) + { + if(entry.getValue() instanceof NoLocalFilter) + { + actualFilters.put(entry.getKey(), entry.getValue()); + noLocal = true; + } + else if(messageFilter == null && entry.getValue() instanceof org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter) + { + + org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter selectorFilter = (org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter) entry.getValue(); + try + { + messageFilter = new JMSSelectorFilter(selectorFilter.getValue()); + + actualFilters.put(entry.getKey(), entry.getValue()); + } + catch (ParseException e) + { + Error error = new Error(); + error.setCondition(AmqpError.INVALID_FIELD); + error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue()); + error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter"))); + throw new AmqpErrorException(error); + } + catch (SelectorParsingException e) + { + Error error = new Error(); + error.setCondition(AmqpError.INVALID_FIELD); + error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue()); + error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter"))); + throw new AmqpErrorException(error); + } + + + } + } + } + source.setFilter(actualFilters.isEmpty() ? null : actualFilters); + + _subscription = new Subscription_1_0(this, qd); + } + else if(destination instanceof ExchangeDestination) + { + try + { + + ExchangeDestination exchangeDestination = (ExchangeDestination) destination; + + boolean isDurable = exchangeDestination.getDurability() == TerminusDurability.CONFIGURATION + || exchangeDestination.getDurability() == TerminusDurability.UNSETTLED_STATE; + String name; + if(isDurable) + { + String remoteContainerId = getEndpoint().getSession().getConnection().getRemoteContainerId(); + remoteContainerId = remoteContainerId.replace("_","__").replace(".", "_:"); + + String endpointName = linkAttachment.getEndpoint().getName(); + endpointName = endpointName + .replace("_", "__") + .replace(".", "_:") + .replace("(", "_O") + .replace(")", "_C") + .replace("<", "_L") + .replace(">", "_R"); + name = "qpid_/" + remoteContainerId + "_/" + endpointName; + } + else + { + name = UUID.randomUUID().toString(); + } + + queue = _vhost.getQueueRegistry().getQueue(name); + Exchange exchange = exchangeDestination.getExchange(); + + if(queue == null) + { + queue = AMQQueueFactory.createAMQQueueImpl( + name, + isDurable, + null, + true, + true, + _vhost, + Collections.EMPTY_MAP); + } + else + { + List<Binding> bindings = queue.getBindings(); + List<Binding> bindingsToRemove = new ArrayList<Binding>(); + for(Binding existingBinding : bindings) + { + if(existingBinding.getExchange() != _vhost.getExchangeRegistry().getDefaultExchange() + && existingBinding.getExchange() != exchange) + { + bindingsToRemove.add(existingBinding); + } + } + for(Binding existingBinding : bindingsToRemove) + { + existingBinding.getExchange().removeBinding(existingBinding); + } + } + + + String binding = ""; + + Map<Symbol,Filter> filters = source.getFilter(); + Map<Symbol,Filter> actualFilters = new HashMap<Symbol,Filter>(); + boolean hasBindingFilter = false; + if(filters != null && !filters.isEmpty()) + { + + for(Map.Entry<Symbol,Filter> entry : filters.entrySet()) + { + if(!hasBindingFilter + && entry.getValue() instanceof ExactSubjectFilter + && exchange.getType() == DirectExchange.TYPE) + { + ExactSubjectFilter filter = (ExactSubjectFilter) filters.values().iterator().next(); + source.setFilter(filters); + binding = filter.getValue(); + actualFilters.put(entry.getKey(), entry.getValue()); + hasBindingFilter = true; + } + else if(!hasBindingFilter + && entry.getValue() instanceof MatchingSubjectFilter + && exchange.getType() == TopicExchange.TYPE) + { + MatchingSubjectFilter filter = (MatchingSubjectFilter) filters.values().iterator().next(); + source.setFilter(filters); + binding = filter.getValue(); + actualFilters.put(entry.getKey(), entry.getValue()); + hasBindingFilter = true; + } + else if(entry.getValue() instanceof NoLocalFilter) + { + actualFilters.put(entry.getKey(), entry.getValue()); + noLocal = true; + } + else if(messageFilter == null && entry.getValue() instanceof org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter) + { + + org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter selectorFilter = (org.apache.qpid.amqp_1_0.type.messaging.JMSSelectorFilter) entry.getValue(); + try + { + messageFilter = new JMSSelectorFilter(selectorFilter.getValue()); + + actualFilters.put(entry.getKey(), entry.getValue()); + } + catch (ParseException e) + { + Error error = new Error(); + error.setCondition(AmqpError.INVALID_FIELD); + error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue()); + error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter"))); + throw new AmqpErrorException(error); + } + catch (SelectorParsingException e) + { + Error error = new Error(); + error.setCondition(AmqpError.INVALID_FIELD); + error.setDescription("Invalid JMS Selector: " + selectorFilter.getValue()); + error.setInfo(Collections.singletonMap(Symbol.valueOf("field"), Symbol.valueOf("filter"))); + throw new AmqpErrorException(error); + } + + + } + } + } + source.setFilter(actualFilters.isEmpty() ? null : actualFilters); + + vhost.getBindingFactory().addBinding(binding,queue,exchange,null); + source.setDistributionMode(StdDistMode.COPY); + + qd = new QueueDestination(queue); + } + catch (AMQSecurityException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + catch (AMQInternalException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } catch (AMQException e) + { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + _subscription = new Subscription_1_0(this, qd, true); + + } + + if(_subscription != null) + { + _subscription.setNoLocal(noLocal); + if(messageFilter!=null) + { + _subscription.setFilters(new SimpleFilterManager(messageFilter)); + } + + try + { + + queue.registerSubscription(_subscription, false); + } + catch (AMQException e) + { + e.printStackTrace(); //TODO + } + } + + } + + public void resume(SendingLinkAttachment linkAttachment) + { + _linkAttachment = linkAttachment; + + } + + public void remoteDetached(final LinkEndpoint endpoint, final Detach detach) + { + //TODO + // if not durable or close + if(!TerminusDurability.UNSETTLED_STATE.equals(_durability) || + (detach != null && Boolean.TRUE.equals(detach.getClosed()))) + { + + AMQQueue queue = _subscription.getQueue(); + + try + { + + queue.unregisterSubscription(_subscription); + + } + catch (AMQException e) + { + e.printStackTrace(); //TODO + } + + DeliveryState state = new Released(); + + for(UnsettledAction action : _unsettledActionMap.values()) + { + + action.process(state,Boolean.TRUE); + } + _unsettledActionMap.clear(); + + endpoint.close(); + + if(_destination instanceof ExchangeDestination + && (_durability == TerminusDurability.CONFIGURATION + || _durability == TerminusDurability.UNSETTLED_STATE)) + { + try + { + queue.delete(); + } + catch(AMQException e) + { + e.printStackTrace(); // TODO - Implement + } + } + + if(_closeAction != null) + { + _closeAction.run(); + } + } + else if(detach == null || detach.getError() != null) + { + _linkAttachment = null; + _subscription.flowStateChanged(); + } + else + { + endpoint.detach(); + } + } + + public void start() + { + //TODO + } + + public SendingLinkEndpoint getEndpoint() + { + return _linkAttachment == null ? null : _linkAttachment.getEndpoint() ; + } + + public Session_1_0 getSession() + { + return _linkAttachment == null ? null : _linkAttachment.getSession(); + } + + public void flowStateChanged() + { + if(Boolean.TRUE.equals(getEndpoint().getDrain()) + && hasCredit()) + { + _draining = true; + } + + while(!_resumeAcceptedTransfers.isEmpty() && getEndpoint().hasCreditToSend()) + { + Accepted accepted = new Accepted(); + synchronized(getLock()) + { + + Transfer xfr = new Transfer(); + Binary dt = _resumeAcceptedTransfers.remove(0); + xfr.setDeliveryTag(dt); + xfr.setState(accepted); + xfr.setResume(Boolean.TRUE); + getEndpoint().transfer(xfr); + } + + } + if(_resumeAcceptedTransfers.isEmpty()) + { + _subscription.flowStateChanged(); + } + + } + + boolean hasCredit() + { + return getEndpoint().getLinkCredit().compareTo(UnsignedInteger.ZERO) > 0; + } + + public boolean isDraining() + { + return false; //TODO + } + + public boolean drained() + { + if(getEndpoint() != null) + { + synchronized(getEndpoint().getLock()) + { + if(_draining) + { + //TODO + getEndpoint().drained(); + _draining = false; + return true; + } + else + { + return false; + } + } + } + else + { + return false; + } + } + + public void addUnsettled(Binary tag, UnsettledAction unsettledAction, QueueEntry queueEntry) + { + _unsettledActionMap.put(tag,unsettledAction); + if(getTransactionId() == null) + { + _unsettledMap.put(tag, queueEntry); + } + } + + public void removeUnsettled(Binary tag) + { + _unsettledActionMap.remove(tag); + } + + public void handle(Binary deliveryTag, DeliveryState state, Boolean settled) + { + UnsettledAction action = _unsettledActionMap.get(deliveryTag); + boolean localSettle = false; + if(action != null) + { + localSettle = action.process(state, settled); + if(localSettle && !Boolean.TRUE.equals(settled)) + { + _linkAttachment.updateDisposition(deliveryTag, state, true); + } + } + if(Boolean.TRUE.equals(settled) || localSettle) + { + _unsettledActionMap.remove(deliveryTag); + _unsettledMap.remove(deliveryTag); + } + } + + ServerTransaction getTransaction(Binary transactionId) + { + return _linkAttachment.getSession().getTransaction(transactionId); + } + + public Binary getTransactionId() + { + SendingLinkEndpoint endpoint = getEndpoint(); + return endpoint == null ? null : endpoint.getTransactionId(); + } + + public synchronized Object getLock() + { + return _linkAttachment == null ? this : getEndpoint().getLock(); + } + + public boolean isDetached() + { + return _linkAttachment == null || getEndpoint().isDetached(); + } + + public boolean isAttached() + { + return _linkAttachment != null && getEndpoint().isAttached(); + } + + public synchronized void setLinkAttachment(SendingLinkAttachment linkAttachment) + { + + if(_subscription.isActive()) + { + _subscription.suspend(); + } + + _linkAttachment = linkAttachment; + + SendingLinkEndpoint endpoint = linkAttachment.getEndpoint(); + endpoint.setDeliveryStateHandler(this); + Map initialUnsettledMap = endpoint.getInitialUnsettledMap(); + Map<Binary, QueueEntry> unsettledCopy = new HashMap<Binary, QueueEntry>(_unsettledMap); + _resumeAcceptedTransfers.clear(); + _resumeFullTransfers.clear(); + + for(Map.Entry<Binary, QueueEntry> entry : unsettledCopy.entrySet()) + { + Binary deliveryTag = entry.getKey(); + final QueueEntry queueEntry = entry.getValue(); + if(initialUnsettledMap == null || !initialUnsettledMap.containsKey(deliveryTag)) + { + queueEntry.setRedelivered(); + queueEntry.release(); + _unsettledMap.remove(deliveryTag); + } + else if(initialUnsettledMap != null && (initialUnsettledMap.get(deliveryTag) instanceof Outcome)) + { + Outcome outcome = (Outcome) initialUnsettledMap.get(deliveryTag); + + if(outcome instanceof Accepted) + { + AutoCommitTransaction txn = new AutoCommitTransaction(_vhost.getMessageStore()); + if(_subscription.acquires()) + { + txn.dequeue(Collections.singleton(queueEntry), + new ServerTransaction.Action() + { + public void postCommit() + { + queueEntry.discard(); + } + + public void onRollback() + { + //To change body of implemented methods use File | Settings | File Templates. + } + }); + } + } + else if(outcome instanceof Released) + { + AutoCommitTransaction txn = new AutoCommitTransaction(_vhost.getMessageStore()); + if(_subscription.acquires()) + { + txn.dequeue(Collections.singleton(queueEntry), + new ServerTransaction.Action() + { + public void postCommit() + { + queueEntry.release(); + } + + public void onRollback() + { + //To change body of implemented methods use File | Settings | File Templates. + } + }); + } + } + //_unsettledMap.remove(deliveryTag); + initialUnsettledMap.remove(deliveryTag); + _resumeAcceptedTransfers.add(deliveryTag); + } + else + { + _resumeFullTransfers.add(queueEntry); + // exists in receivers map, but not yet got an outcome ... should resend with resume = true + } + // TODO - else + } + + + } + + public Map getUnsettledOutcomeMap() + { + Map<Binary, QueueEntry> unsettled = new HashMap<Binary, QueueEntry>(_unsettledMap); + + for(Map.Entry<Binary, QueueEntry> entry : unsettled.entrySet()) + { + entry.setValue(null); + } + + return unsettled; + } + + public void setCloseAction(Runnable action) + { + _closeAction = action; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java new file mode 100644 index 0000000000..3f7eb18989 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Session_1_0.java @@ -0,0 +1,440 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +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.SendingLinkEndpoint; +import org.apache.qpid.amqp_1_0.transport.SessionEventListener; +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.LifetimePolicy; +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.transaction.Coordinator; +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 org.apache.qpid.AMQException; +import org.apache.qpid.AMQSecurityException; +import org.apache.qpid.server.exchange.Exchange; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.registry.IApplicationRegistry; +import org.apache.qpid.server.txn.AutoCommitTransaction; +import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.virtualhost.VirtualHost; + +import java.util.*; + +public class Session_1_0 implements SessionEventListener +{ + private static final Symbol LIFETIME_POLICY = Symbol.valueOf("lifetime-policy"); + private IApplicationRegistry _appRegistry; + private VirtualHost _vhost; + private AutoCommitTransaction _transaction; + + private final LinkedHashMap<Integer, ServerTransaction> _openTransactions = + new LinkedHashMap<Integer, ServerTransaction>(); + private final Connection_1_0 _connection; + + + public Session_1_0(VirtualHost vhost, IApplicationRegistry appRegistry, final Connection_1_0 connection) + { + _appRegistry = appRegistry; + _vhost = vhost; + _transaction = new AutoCommitTransaction(vhost.getMessageStore()); + _connection = connection; + + } + + public void remoteLinkCreation(final LinkEndpoint endpoint) + { + + + Destination destination; + Link_1_0 link = null; + Error error = null; + + final LinkRegistry linkRegistry = _vhost.getLinkRegistry(endpoint.getSession().getConnection().getRemoteContainerId()); + + + if(endpoint.getRole() == Role.SENDER) + { + + SendingLink_1_0 previousLink = linkRegistry.getDurableSendingLink(endpoint.getName()); + + if(previousLink == null) + { + + Target target = (Target) endpoint.getTarget(); + Source source = (Source) endpoint.getSource(); + + + if(source != null) + { + if(Boolean.TRUE.equals(source.getDynamic())) + { + AMQQueue tempQueue = createTemporaryQueue(source.getDynamicNodeProperties()); + source.setAddress(tempQueue.getName()); + } + String addr = source.getAddress(); + AMQQueue queue = _vhost.getQueueRegistry().getQueue(addr); + if(queue != null) + { + + destination = new QueueDestination(queue); + + + + } + else + { + Exchange exchg = _vhost.getExchangeRegistry().getExchange(addr); + if(exchg != null) + { + destination = new ExchangeDestination(exchg, source.getDurable(), source.getExpiryPolicy()); + } + else + { + + endpoint.setSource(null); + destination = null; + } + } + + } + else + { + destination = null; + } + + if(destination != null) + { + final SendingLinkEndpoint sendingLinkEndpoint = (SendingLinkEndpoint) endpoint; + try + { + final SendingLink_1_0 sendingLink = new SendingLink_1_0(new SendingLinkAttachment(this, sendingLinkEndpoint), + _vhost, + (SendingDestination) destination + ); + sendingLinkEndpoint.setLinkEventListener(sendingLink); + link = sendingLink; + if(TerminusDurability.UNSETTLED_STATE.equals(source.getDurable())) + { + linkRegistry.registerSendingLink(endpoint.getName(), sendingLink); + sendingLink.setCloseAction(new Runnable() { + + public void run() + { + linkRegistry.unregisterSendingLink(endpoint.getName()); + } + }); + } + } + catch(AmqpErrorException e) + { + e.printStackTrace(); + destination = null; + sendingLinkEndpoint.setSource(null); + error = e.getError(); + } + } + } + else + { + endpoint.setSource(previousLink.getEndpoint().getSource()); + SendingLinkEndpoint sendingLinkEndpoint = (SendingLinkEndpoint) endpoint; + previousLink.setLinkAttachment(new SendingLinkAttachment(this, sendingLinkEndpoint)); + sendingLinkEndpoint.setLinkEventListener(previousLink); + link = previousLink; + endpoint.setLocalUnsettled(previousLink.getUnsettledOutcomeMap()); + } + } + else + { + if(endpoint.getTarget() instanceof Coordinator) + { + Coordinator coordinator = (Coordinator) endpoint.getTarget(); + TxnCapability[] capabilities = coordinator.getCapabilities(); + boolean localTxn = false; + boolean multiplePerSession = false; + if(capabilities != null) + { + for(TxnCapability capability : capabilities) + { + if(capability.equals(TxnCapability.LOCAL_TXN)) + { + localTxn = true; + } + else if(capability.equals(TxnCapability.MULTI_TXNS_PER_SSN)) + { + multiplePerSession = true; + } + else + { + error = new Error(); + error.setCondition(AmqpError.NOT_IMPLEMENTED); + error.setDescription("Unsupported capability: " + capability); + break; + } + } + } + + /* if(!localTxn) + { + capabilities.add(TxnCapabilities.LOCAL_TXN); + }*/ + + final ReceivingLinkEndpoint receivingLinkEndpoint = (ReceivingLinkEndpoint) endpoint; + final TxnCoordinatorLink_1_0 coordinatorLink = + new TxnCoordinatorLink_1_0(_vhost, this, receivingLinkEndpoint, _openTransactions); + receivingLinkEndpoint.setLinkEventListener(coordinatorLink); + link = coordinatorLink; + + + } + else + { + + ReceivingLink_1_0 previousLink = linkRegistry.getDurableReceivingLink(endpoint.getName()); + + if(previousLink == null) + { + + Target target = (Target) endpoint.getTarget(); + + if(target != null) + { + if(Boolean.TRUE.equals(target.getDynamic())) + { + + AMQQueue tempQueue = createTemporaryQueue(target.getDynamicNodeProperties()); + target.setAddress(tempQueue.getName()); + } + + String addr = target.getAddress(); + Exchange exchg = _vhost.getExchangeRegistry().getExchange(addr); + if(exchg != null) + { + destination = new ExchangeDestination(exchg, target.getDurable(), + target.getExpiryPolicy()); + } + else + { + AMQQueue queue = _vhost.getQueueRegistry().getQueue(addr); + if(queue != null) + { + + destination = new QueueDestination(queue); + } + else + { + endpoint.setTarget(null); + destination = null; + } + + } + + + } + else + { + destination = null; + } + if(destination != null) + { + final ReceivingLinkEndpoint receivingLinkEndpoint = (ReceivingLinkEndpoint) endpoint; + final ReceivingLink_1_0 receivingLink = new ReceivingLink_1_0(new ReceivingLinkAttachment(this, receivingLinkEndpoint), _vhost, + (ReceivingDestination) destination); + receivingLinkEndpoint.setLinkEventListener(receivingLink); + link = receivingLink; + if(TerminusDurability.UNSETTLED_STATE.equals(target.getDurable())) + { + linkRegistry.registerReceivingLink(endpoint.getName(), receivingLink); + } + } + } + else + { + ReceivingLinkEndpoint receivingLinkEndpoint = (ReceivingLinkEndpoint) endpoint; + previousLink.setLinkAttachment(new ReceivingLinkAttachment(this, receivingLinkEndpoint)); + receivingLinkEndpoint.setLinkEventListener(previousLink); + link = previousLink; + endpoint.setLocalUnsettled(previousLink.getUnsettledOutcomeMap()); + + } + } + } + + endpoint.attach(); + + if(link == null) + { + if(error == null) + { + error = new Error(); + error.setCondition(AmqpError.NOT_FOUND); + } + endpoint.detach(error); + } + else + { + link.start(); + } + } + + + private AMQQueue createTemporaryQueue(Map properties) + { + final String queueName = UUID.randomUUID().toString(); + AMQQueue queue = null; + try + { + LifetimePolicy lifetimePolicy = properties == null + ? null + : (LifetimePolicy) properties.get(LIFETIME_POLICY); + + final AMQQueue tempQueue = queue = AMQQueueFactory.createAMQQueueImpl(queueName, + false, // durable + null, // owner + false, // autodelete + false, // exclusive + _vhost, + properties); + + + + if (lifetimePolicy == null || lifetimePolicy instanceof DeleteOnClose) + { + final Connection_1_0.Task deleteQueueTask = + new Connection_1_0.Task() + { + public void doTask(Connection_1_0 session) + { + if (_vhost.getQueueRegistry().getQueue(queueName) == tempQueue) + { + try + { + tempQueue.delete(); + } + catch (AMQException e) + { + e.printStackTrace(); //TODO. + } + } + } + }; + + _connection.addConnectionCloseTask(deleteQueueTask); + + queue.addQueueDeleteTask(new AMQQueue.Task() + { + public void doTask(AMQQueue queue) + { + _connection.removeConnectionCloseTask(deleteQueueTask); + } + + + }); + } + else if(lifetimePolicy instanceof DeleteOnNoLinks) + { + + } + else if(lifetimePolicy instanceof DeleteOnNoMessages) + { + + } + else if(lifetimePolicy instanceof DeleteOnNoLinksOrMessages) + { + + } + } + catch (AMQSecurityException e) + { + e.printStackTrace(); //TODO. + } catch (AMQException e) + { + e.printStackTrace(); //TODO + } + + return queue; + } + + public ServerTransaction getTransaction(Binary transactionId) + { + // TODO should treat invalid id differently to null + ServerTransaction transaction = _openTransactions.get(binaryToInteger(transactionId)); + return transaction == null ? _transaction : transaction; + } + + public void remoteEnd(End end) + { + Iterator<Map.Entry<Integer, ServerTransaction>> iter = _openTransactions.entrySet().iterator(); + + while(iter.hasNext()) + { + Map.Entry<Integer, ServerTransaction> entry = iter.next(); + entry.getValue().rollback(); + iter.remove(); + } + + } + + Integer binaryToInteger(final Binary txnId) + { + if(txnId == null) + { + return null; + } + + if(txnId.getLength() > 4) + throw new IllegalArgumentException(); + + int id = 0; + byte[] data = txnId.getArray(); + for(int i = 0; i < txnId.getLength(); i++) + { + id <<= 8; + id += data[i+txnId.getArrayOffset()]; + } + + return id; + + } + + Binary integerToBinary(final int txnId) + { + byte[] data = new byte[4]; + data[3] = (byte) (txnId & 0xff); + data[2] = (byte) ((txnId & 0xff00) >> 8); + data[1] = (byte) ((txnId & 0xff0000) >> 16); + data[0] = (byte) ((txnId & 0xff000000) >> 24); + return new Binary(data); + + } + + public void forceEnd() + { + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java new file mode 100644 index 0000000000..425f63dd90 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/Subscription_1_0.java @@ -0,0 +1,621 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantLock; +import org.apache.qpid.AMQException; +import org.apache.qpid.amqp_1_0.codec.DescribedTypeConstructorRegistry; +import org.apache.qpid.amqp_1_0.codec.ValueHandler; +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.type.AmqpErrorException; +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.UnsignedInteger; +import org.apache.qpid.amqp_1_0.type.codec.AMQPDescribedTypeRegistry; +import org.apache.qpid.amqp_1_0.type.messaging.Accepted; +import org.apache.qpid.amqp_1_0.type.messaging.Header; +import org.apache.qpid.amqp_1_0.type.messaging.Modified; +import org.apache.qpid.amqp_1_0.type.messaging.Released; +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.transaction.TransactionalState; +import org.apache.qpid.amqp_1_0.type.transport.SenderSettleMode; +import org.apache.qpid.amqp_1_0.type.transport.Transfer; +import org.apache.qpid.server.filter.FilterManager; +import org.apache.qpid.server.logging.LogActor; +import org.apache.qpid.server.message.ServerMessage; +import org.apache.qpid.server.queue.AMQQueue; +import org.apache.qpid.server.queue.QueueEntry; +import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.txn.ServerTransaction; + +class Subscription_1_0 implements Subscription +{ + private SendingLink_1_0 _link; + + private AMQQueue _queue; + + private final AtomicReference<State> _state = new AtomicReference<State>(State.SUSPENDED); + + private final QueueEntry.SubscriptionAcquiredState _owningState = new QueueEntry.SubscriptionAcquiredState(this); + private final QueueEntry.SubscriptionAssignedState _assignedState = new QueueEntry.SubscriptionAssignedState(this); + private final long _id; + private final boolean _acquires; + private AMQQueue.Context _queueContext; + private Map<String, Object> _properties = new ConcurrentHashMap<String, Object>(); + private ReentrantLock _stateChangeLock = new ReentrantLock(); + + private boolean _noLocal; + private FilterManager _filters; + + private long _deliveryTag = 0L; + private StateListener _stateListener; + + private Binary _transactionId; + private final AMQPDescribedTypeRegistry _typeRegistry = AMQPDescribedTypeRegistry.newInstance() + .registerTransportLayer() + .registerMessagingLayer() + .registerTransactionLayer() + .registerSecurityLayer(); + private SectionEncoder _sectionEncoder = new SectionEncoderImpl(_typeRegistry); + + public Subscription_1_0(final SendingLink_1_0 link, final QueueDestination destination) + { + this(link, destination, ((Source)link.getEndpoint().getSource()).getDistributionMode() != StdDistMode.COPY); + } + + public Subscription_1_0(final SendingLink_1_0 link, final QueueDestination destination, boolean acquires) + { + _link = link; + _queue = destination.getQueue(); + _id = getEndpoint().getLocalHandle().longValue(); + _acquires = acquires; + } + + private SendingLinkEndpoint getEndpoint() + { + return _link.getEndpoint(); + } + + public LogActor getLogActor() + { + return null; //TODO + } + + public boolean isTransient() + { + return true; //TODO + } + + public AMQQueue getQueue() + { + return _queue; + } + + public QueueEntry.SubscriptionAcquiredState getOwningState() + { + return _owningState; + } + + public QueueEntry.SubscriptionAssignedState getAssignedState() + { + return _assignedState; + } + + public void setQueue(final AMQQueue queue, final boolean exclusive) + { + //TODO + } + + public void setNoLocal(final boolean noLocal) + { + _noLocal = noLocal; + } + + public boolean isNoLocal() + { + return _noLocal; + } + + public long getSubscriptionID() + { + return _id; + } + + public boolean isSuspended() + { + return !isActive();// || !getEndpoint().hasCreditToSend(); + + } + + public boolean hasInterest(final QueueEntry entry) + { + return !(_noLocal && (entry.getMessage() instanceof Message_1_0) + && ((Message_1_0)entry.getMessage()).getSession() == getSession()) + && checkFilters(entry); + + } + + private boolean checkFilters(final QueueEntry entry) + { + return (_filters == null) || _filters.allAllow(entry); + } + + public boolean isClosed() + { + return !getEndpoint().isAttached(); + } + + public boolean acquires() + { + return _acquires; + } + + public boolean seesRequeues() + { + // TODO + return acquires(); + } + + public void close() + { + getEndpoint().detach(); + } + + public void send(QueueEntry entry, boolean batch) throws AMQException + { + // TODO + send(entry); + } + + public void flushBatched() + { + // TODO + } + + public void send(final QueueEntry queueEntry) throws AMQException + { + //TODO + ServerMessage serverMessage = queueEntry.getMessage(); + if(serverMessage instanceof Message_1_0) + { + Message_1_0 message = (Message_1_0) serverMessage; + Transfer transfer = new Transfer(); + //TODO + + + List<ByteBuffer> fragments = message.getFragments(); + ByteBuffer payload; + if(fragments.size() == 1) + { + payload = fragments.get(0); + } + else + { + int size = 0; + for(ByteBuffer fragment : fragments) + { + size += fragment.remaining(); + } + + payload = ByteBuffer.allocate(size); + + for(ByteBuffer fragment : fragments) + { + payload.put(fragment.duplicate()); + } + + payload.flip(); + } + + if(queueEntry.getDeliveryCount() != 0) + { + payload = payload.duplicate(); + ValueHandler valueHandler = new ValueHandler(_typeRegistry); + + Header oldHeader = null; + try + { + ByteBuffer encodedBuf = payload.duplicate(); + Object value = valueHandler.parse(payload); + if(value instanceof Header) + { + oldHeader = (Header) value; + } + else + { + payload.position(0); + } + } + catch (AmqpErrorException e) + { + //TODO + throw new RuntimeException(e); + } + + Header header = new Header(); + if(oldHeader != null) + { + header.setDurable(oldHeader.getDurable()); + header.setPriority(oldHeader.getPriority()); + header.setTtl(oldHeader.getTtl()); + } + header.setDeliveryCount(UnsignedInteger.valueOf(queueEntry.getDeliveryCount())); + _sectionEncoder.reset(); + _sectionEncoder.encodeObject(header); + Binary encodedHeader = _sectionEncoder.getEncoding(); + + ByteBuffer oldPayload = payload; + payload = ByteBuffer.allocate(oldPayload.remaining() + encodedHeader.getLength()); + payload.put(encodedHeader.getArray(),encodedHeader.getArrayOffset(),encodedHeader.getLength()); + payload.put(oldPayload); + payload.flip(); + } + + transfer.setPayload(payload); + byte[] data = new byte[8]; + ByteBuffer.wrap(data).putLong(_deliveryTag++); + final Binary tag = new Binary(data); + + transfer.setDeliveryTag(tag); + + synchronized(_link.getLock()) + { + if(_link.isAttached()) + { + if(SenderSettleMode.SETTLED.equals(getEndpoint().getSendingSettlementMode())) + { + transfer.setSettled(true); + } + else + { + UnsettledAction action = _acquires + ? new DispositionAction(tag, queueEntry) + : new DoNothingAction(tag, queueEntry); + + _link.addUnsettled(tag, action, queueEntry); + } + + if(_transactionId != null) + { + TransactionalState state = new TransactionalState(); + state.setTxnId(_transactionId); + transfer.setState(state); + } + // TODO - need to deal with failure here + if(_acquires && _transactionId != null) + { + ServerTransaction txn = _link.getTransaction(_transactionId); + if(txn != null) + { + txn.addPostTransactionAction(new ServerTransaction.Action(){ + + public void postCommit() + { + //To change body of implemented methods use File | Settings | File Templates. + } + + public void onRollback() + { + if(queueEntry.isAcquiredBy(Subscription_1_0.this)) + { + queueEntry.release(); + _link.getEndpoint().updateDisposition(tag, (DeliveryState)null, true); + + + } + } + }); + } + + } + + getEndpoint().transfer(transfer); + } + else + { + queueEntry.release(); + } + } + } + + } + + public void queueDeleted(final AMQQueue queue) + { + //TODO + getEndpoint().setSource(null); + getEndpoint().detach(); + } + + public synchronized boolean wouldSuspend(final QueueEntry msg) + { + final boolean hasCredit = _link.isAttached() && getEndpoint().hasCreditToSend(); + if(!hasCredit && getState() == State.ACTIVE) + { + suspend(); + } + + return !hasCredit; + } + + public boolean trySendLock() + { + return _stateChangeLock.tryLock(); + } + + public synchronized void suspend() + { + if(_state.compareAndSet(State.ACTIVE, State.SUSPENDED)) + { + _stateListener.stateChange(this, State.ACTIVE, State.SUSPENDED); + } + } + + public void getSendLock() + { + _stateChangeLock.lock(); + } + + public void releaseSendLock() + { + _stateChangeLock.unlock(); + } + + public void releaseQueueEntry(QueueEntry queueEntryImpl) + { + //To change body of implemented methods use File | Settings | File Templates. + } + + + public void onDequeue(final QueueEntry queueEntry) + { + //TODO + } + + public void restoreCredit(final QueueEntry queueEntry) + { + //TODO + } + + public void setStateListener(final StateListener listener) + { + _stateListener = listener; + } + + public State getState() + { + return _state.get(); + } + + public AMQQueue.Context getQueueContext() + { + return _queueContext; + } + + public void setQueueContext(AMQQueue.Context queueContext) + { + _queueContext = queueContext; + } + + + public boolean isActive() + { + return getState() == State.ACTIVE; + } + + public void set(String key, Object value) + { + _properties.put(key, value); + } + + public Object get(String key) + { + return _properties.get(key); + } + + public boolean isSessionTransactional() + { + return false; //TODO + } + + public synchronized void queueEmpty() + { + if(_link.drained()) + { + if(_state.compareAndSet(State.ACTIVE, State.SUSPENDED)) + { + _stateListener.stateChange(this, State.ACTIVE, State.SUSPENDED); + } + } + } + + public synchronized void flowStateChanged() + { + if(isSuspended() && getEndpoint() != null) + { + if(_state.compareAndSet(State.SUSPENDED, State.ACTIVE)) + { + _stateListener.stateChange(this, State.SUSPENDED, State.ACTIVE); + } + _transactionId = _link.getTransactionId(); + } + } + + public Session_1_0 getSession() + { + return _link.getSession(); + } + + private class DispositionAction implements UnsettledAction + { + + private final QueueEntry _queueEntry; + private final Binary _deliveryTag; + + public DispositionAction(Binary tag, QueueEntry queueEntry) + { + _deliveryTag = tag; + _queueEntry = queueEntry; + } + + public boolean process(DeliveryState state, Boolean settled) + { + + Binary transactionId = null; + final Outcome outcome; + // If disposition is settled this overrides the txn? + if(state instanceof TransactionalState) + { + transactionId = ((TransactionalState)state).getTxnId(); + outcome = ((TransactionalState)state).getOutcome(); + } + else if (state instanceof Outcome) + { + outcome = (Outcome) state; + } + else + { + outcome = null; + } + + + ServerTransaction txn = _link.getTransaction(transactionId); + + if(outcome instanceof Accepted) + { + txn.dequeue(_queueEntry.getQueue(), _queueEntry.getMessage(), + new ServerTransaction.Action() + { + + public void postCommit() + { + if(_queueEntry.isAcquiredBy(Subscription_1_0.this)) + { + _queueEntry.discard(); + } + } + + public void onRollback() + { + + } + }); + txn.addPostTransactionAction(new ServerTransaction.Action() + { + public void postCommit() + { + //_link.getEndpoint().settle(_deliveryTag); + _link.getEndpoint().updateDisposition(_deliveryTag, (DeliveryState)outcome, true); + _link.getEndpoint().sendFlowConditional(); + } + + public void onRollback() + { + } + }); + } + else if(outcome instanceof Released) + { + txn.addPostTransactionAction(new ServerTransaction.Action() + { + public void postCommit() + { + + _queueEntry.release(); + _link.getEndpoint().settle(_deliveryTag); + } + + public void onRollback() + { + _link.getEndpoint().settle(_deliveryTag); + } + }); + } + + else if(outcome instanceof Modified) + { + txn.addPostTransactionAction(new ServerTransaction.Action() + { + public void postCommit() + { + + _queueEntry.release(); + _queueEntry.incrementDeliveryCount(); + _link.getEndpoint().settle(_deliveryTag); + } + + public void onRollback() + { + _link.getEndpoint().settle(_deliveryTag); + } + }); + } + + return (transactionId == null && outcome != null); + } + } + + private class DoNothingAction implements UnsettledAction + { + public DoNothingAction(final Binary tag, + final QueueEntry queueEntry) + { + } + + public boolean process(final DeliveryState state, final Boolean settled) + { + Binary transactionId = null; + Outcome outcome = null; + // If disposition is settled this overrides the txn? + if(state instanceof TransactionalState) + { + transactionId = ((TransactionalState)state).getTxnId(); + outcome = ((TransactionalState)state).getOutcome(); + } + else if (state instanceof Outcome) + { + outcome = (Outcome) state; + } + return true; + } + } + + public FilterManager getFilters() + { + return _filters; + } + + public void setFilters(final FilterManager filters) + { + _filters = filters; + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java new file mode 100644 index 0000000000..a05d14816a --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/TxnCoordinatorLink_1_0.java @@ -0,0 +1,195 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.protocol.v1_0; + +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.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.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.*; +import org.apache.qpid.amqp_1_0.type.transport.Error; +import org.apache.qpid.server.txn.LocalTransaction; +import org.apache.qpid.server.txn.ServerTransaction; +import org.apache.qpid.server.virtualhost.VirtualHost; + +import java.nio.ByteBuffer; +import java.util.*; + +public class TxnCoordinatorLink_1_0 implements ReceivingLinkListener, Link_1_0 +{ + private VirtualHost _vhost; + private ReceivingLinkEndpoint _endpoint; + + private ArrayList<Transfer> _incompleteMessage; + private SectionDecoder _sectionDecoder; + private LinkedHashMap<Integer, ServerTransaction> _openTransactions; + private Session_1_0 _session; + + + public TxnCoordinatorLink_1_0(VirtualHost vhost, + Session_1_0 session_1_0, ReceivingLinkEndpoint endpoint, + LinkedHashMap<Integer, ServerTransaction> openTransactions) + { + _vhost = vhost; + _session = session_1_0; + _endpoint = endpoint; + _sectionDecoder = new SectionDecoderImpl(endpoint.getSession().getConnection().getDescribedTypeRegistry()); + _openTransactions = openTransactions; + } + + public void messageTransfer(Transfer xfr) + { + // TODO - cope with fragmented messages + + ByteBuffer payload = null; + + + if(Boolean.TRUE.equals(xfr.getMore()) && _incompleteMessage == null) + { + _incompleteMessage = new ArrayList<Transfer>(); + _incompleteMessage.add(xfr); + return; + } + else if(_incompleteMessage != null) + { + _incompleteMessage.add(xfr); + if(Boolean.TRUE.equals(xfr.getMore())) + { + return; + } + + int size = 0; + for(Transfer t : _incompleteMessage) + { + size += t.getPayload().limit(); + } + payload = ByteBuffer.allocate(size); + for(Transfer t : _incompleteMessage) + { + payload.put(t.getPayload().duplicate()); + } + payload.flip(); + _incompleteMessage=null; + + } + else + { + payload = xfr.getPayload(); + } + + + // Only interested int he amqp-value section that holds the message to the co-ordinator + try + { + List<Section> sections = _sectionDecoder.parseAll(payload); + + for(Section section : sections) + { + if(section instanceof AmqpValue) + { + Object command = ((AmqpValue) section).getValue(); + + if(command instanceof Declare) + { + Integer txnId = Integer.valueOf(0); + Iterator<Integer> existingTxn = _openTransactions.keySet().iterator(); + while(existingTxn.hasNext()) + { + txnId = existingTxn.next(); + } + txnId = Integer.valueOf(txnId.intValue() + 1); + + _openTransactions.put(txnId, new LocalTransaction(_vhost.getMessageStore())); + + Declared state = new Declared(); + + + + state.setTxnId(_session.integerToBinary(txnId)); + _endpoint.updateDisposition(xfr.getDeliveryTag(), state, true); + + } + else if(command instanceof Discharge) + { + Discharge discharge = (Discharge) command; + + DeliveryState state = xfr.getState(); + discharge(_session.binaryToInteger(discharge.getTxnId()), discharge.getFail()); + _endpoint.updateDisposition(xfr.getDeliveryTag(), new Accepted(), true); + + } + } + } + + } + catch (AmqpErrorException e) + { + e.printStackTrace(); //TODO. + } + + } + + public void remoteDetached(LinkEndpoint endpoint, Detach detach) + { + //TODO + endpoint.detach(); + } + + private Error discharge(Integer transactionId, boolean fail) + { + Error error = null; + ServerTransaction txn = _openTransactions.get(transactionId); + if(txn != null) + { + if(fail) + { + txn.rollback(); + } + else + { + txn.commit(); + } + _openTransactions.remove(transactionId); + } + else + { + error = new Error(); + error.setCondition(AmqpError.NOT_FOUND); + error.setDescription("Unkown transactionId" + transactionId); + } + return error; + } + + + + public void start() + { + _endpoint.setLinkCredit(UnsignedInteger.ONE); + _endpoint.setCreditWindow(); + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java new file mode 100644 index 0000000000..c497cc5146 --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/v1_0/UnsettledAction.java @@ -0,0 +1,8 @@ +package org.apache.qpid.server.protocol.v1_0; + +import org.apache.qpid.amqp_1_0.type.DeliveryState; + +public interface UnsettledAction +{ + boolean process(DeliveryState state, Boolean settled); +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java index c8f04c7b96..79279b44c7 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueContext.java @@ -52,4 +52,13 @@ final class QueueContext implements AMQQueue.Context { return _releasedEntry; } + + @Override + public String toString() + { + return "QueueContext{" + + "_lastSeenEntry=" + _lastSeenEntry + + ", _releasedEntry=" + _releasedEntry + + '}'; + } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java index 6c9e918324..209553e8fa 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/QueueEntryImpl.java @@ -227,9 +227,10 @@ public abstract class QueueEntryImpl implements QueueEntry public void release() { EntryState state = _state; - + if((state.getState() == State.ACQUIRED) &&_stateUpdater.compareAndSet(this, state, AVAILABLE_STATE)) { + if(state instanceof SubscriptionAcquiredState) { getQueue().decrementUnackedMsgCount(); @@ -254,6 +255,7 @@ public abstract class QueueEntryImpl implements QueueEntry routeToAlternate(); } } + } public boolean releaseButRetain() @@ -267,7 +269,6 @@ public abstract class QueueEntryImpl implements QueueEntry Subscription sub = ((SubscriptionAcquiredState) state).getSubscription(); if(_stateUpdater.compareAndSet(this, state, sub.getAssignedState())) { - System.err.println("Message released (and retained)" + getMessage().getMessageNumber()); getQueue().requeue(this); if(_stateChangeListeners != null) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java index 1cd7e3505f..e6f059a875 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java @@ -862,7 +862,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes public void requeue(QueueEntry entry) { - SubscriptionList.SubscriptionNodeIterator subscriberIter = _subscriptionList.iterator(); // iterate over all the subscribers, and if they are in advance of this queue entry then move them backwards while (subscriberIter.advance() && entry.isAvailable()) @@ -1743,6 +1742,7 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes { boolean atTail = false; final boolean keepSendLockHeld = iterations <= SimpleAMQQueue.MAX_ASYNC_DELIVERIES; + boolean queueEmpty = false; try { @@ -1760,12 +1760,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes } atTail = attemptDelivery(sub, true); - if (atTail && !sub.isSuspended() && sub.isAutoClose()) + if (atTail && getNextAvailableEntry(sub) == null) { - unregisterSubscription(sub); - - sub.confirmAutoClose(); - + queueEmpty = true; } else if (!atTail) { @@ -1787,6 +1784,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes { sub.releaseSendLock(); } + if(queueEmpty) + { + sub.queueEmpty(); + } + sub.flushBatched(); } @@ -2009,13 +2011,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener, Mes if (subscriptionDone) { sub.flushBatched(); - //close autoClose subscriptions if we are not currently intent on continuing - if (lastLoop && !sub.isSuspended() && sub.isAutoClose()) + if (lastLoop && !sub.isSuspended()) { - - unregisterSubscription(sub); - - sub.confirmAutoClose(); + sub.queueEmpty(); } break; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java index 4ffa5a4bc2..6c1a917d5b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java @@ -24,6 +24,7 @@ import org.apache.qpid.common.Closeable; import org.apache.qpid.server.plugins.Plugin; import org.apache.qpid.server.security.auth.AuthenticationResult; +import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; @@ -88,4 +89,6 @@ public interface AuthenticationManager extends Closeable, Plugin * @return authentication result */ AuthenticationResult authenticate(String username, String password); + + CallbackHandler getHandler(String mechanism); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java index 3fa0de2af0..b5d70d9200 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java @@ -300,6 +300,11 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan } } + public CallbackHandler getHandler(String mechanism) + { + return _callbackHandlerMap.get(mechanism); + } + /** * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(String, String) */ diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java index 3664568b75..4650234972 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java @@ -58,4 +58,4 @@ public class AnonymousSaslServerFactory implements SaslServerFactory return new String[]{AnonymousSaslServer.MECHANISM}; } } -}
\ No newline at end of file +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageMetaDataType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageMetaDataType.java index 428bb1e41b..0fab60b6f3 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageMetaDataType.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/store/MessageMetaDataType.java @@ -22,13 +22,16 @@ package org.apache.qpid.server.store; import org.apache.qpid.server.message.MessageMetaData; import org.apache.qpid.server.message.MessageMetaData_0_10; +import org.apache.qpid.server.message.MessageMetaData_1_0; import java.nio.ByteBuffer; public enum MessageMetaDataType { META_DATA_0_8 { public Factory<MessageMetaData> getFactory() { return MessageMetaData.FACTORY; } }, - META_DATA_0_10 { public Factory<MessageMetaData_0_10> getFactory() { return MessageMetaData_0_10.FACTORY; } }; + META_DATA_0_10 { public Factory<MessageMetaData_0_10> getFactory() { return MessageMetaData_0_10.FACTORY; } }, + META_DATA_1_0 { public Factory<MessageMetaData_1_0> getFactory() { return MessageMetaData_1_0.FACTORY; } }; + public static interface Factory<M extends StorableMessageMetaData> diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java index f8a585b562..66825caa24 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription.java @@ -54,16 +54,12 @@ public interface Subscription void setNoLocal(boolean noLocal); - AMQShortString getConsumerTag(); - long getSubscriptionID(); boolean isSuspended(); boolean hasInterest(QueueEntry msg); - boolean isAutoClose(); - boolean isClosed(); boolean acquires(); @@ -105,11 +101,11 @@ public interface Subscription boolean isActive(); - void confirmAutoClose(); - public void set(String key, Object value); public Object get(String key); boolean isSessionTransactional(); + + void queueEmpty() throws AMQException; } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java index 32baa17fc7..1f25c215cc 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionImpl.java @@ -375,7 +375,7 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage { return getQueue().getConfigStore(); } - + public Long getDelivered() { return _deliveredCount.get(); @@ -810,12 +810,22 @@ public abstract class SubscriptionImpl implements Subscription, FlowCreditManage { return _channel.isTransactional(); } - + public long getCreateTime() { return _createTime; } + public void queueEmpty() throws AMQException + { + if (isAutoClose()) + { + _queue.unregisterSubscription(this); + + confirmAutoClose(); + } + } + public void flushBatched() { _channel.getProtocolSession().setDeferFlush(false); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java index a75467ac42..76d975a789 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/subscription/Subscription_0_10.java @@ -109,7 +109,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr public void stateChange(Subscription sub, State oldState, State newState) { - CurrentActor.get().message(SubscriptionMessages.STATE(newState.toString())); + CurrentActor.get().message(SubscriptionMessages.STATE(newState.toString())); } }; private AMQQueue _queue; @@ -199,12 +199,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr CurrentActor.get().message(this, SubscriptionMessages.CREATE(filterLogString, queue.isDurable() && exclusive, filterLogString.length() > 0)); } - - } - public AMQShortString getConsumerTag() - { - return new AMQShortString(_destination); } public boolean isSuspended() @@ -244,12 +239,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return (_filters == null) || _filters.allAllow(entry); } - public boolean isAutoClose() - { - // no such thing in 0-10 - return false; - } - public boolean isClosed() { return getState() == State.CLOSED; @@ -302,7 +291,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr { return getQueue().getConfigStore(); } - + public Long getDelivered() { return _deliveredCount.get(); @@ -823,11 +812,6 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return getState() == State.ACTIVE; } - public void confirmAutoClose() - { - //No such thing in 0-10 - } - public void set(String key, Object value) { _properties.put(key, value); @@ -1026,6 +1010,10 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr return _session.isTransactional(); } + public void queueEmpty() + { + } + public long getCreateTime() { return _createTime; @@ -1033,7 +1021,7 @@ public class Subscription_0_10 implements Subscription, FlowCreditManager.FlowCr public String toLogString() { - String queueInfo = MessageFormat.format(QUEUE_FORMAT, _queue.getVirtualHost().getName(), + String queueInfo = MessageFormat.format(QUEUE_FORMAT, _queue.getVirtualHost().getName(), _queue.getNameShortString()); String result = "[" + MessageFormat.format(SUBSCRIPTION_FORMAT, getSubscriptionID()) + "(" // queueString is "vh(/{0})/qu({1}) " so need to trim diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java index 70239b0fee..6f979e035e 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java @@ -134,7 +134,7 @@ public class ServerSession extends Session new ConcurrentSkipListMap<Integer, MessageDispositionChangeListener>(); private ServerTransaction _transaction; - + private final AtomicLong _txnStarts = new AtomicLong(0); private final AtomicLong _txnCommits = new AtomicLong(0); private final AtomicLong _txnRejects = new AtomicLong(0); @@ -153,7 +153,7 @@ public class ServerSession extends Session public ServerSession(Connection connection, SessionDelegate delegate, Binary name, long expiry, ConnectionConfig connConfig) { super(connection, delegate, name, expiry); - _connectionConfig = connConfig; + _connectionConfig = connConfig; _transaction = new AsyncAutoCommitTransaction(this.getMessageStore(),this); _logSubject = new ChannelLogSubject(this); _id = getConfigStore().createId(); @@ -353,7 +353,7 @@ public class ServerSession extends Session } } - public void removeDispositionListener(Method method) + public void removeDispositionListener(Method method) { _messageDispositionListenerMap.remove(method.getId()); } @@ -381,7 +381,7 @@ public class ServerSession extends Session { task.doTask(this); } - + CurrentActor.get().message(getLogSubject(), ChannelMessages.CLOSE()); } @@ -430,7 +430,7 @@ public class ServerSession extends Session public void unregister(Subscription_0_10 sub) { - _subscriptions.remove(sub.getConsumerTag().toString()); + _subscriptions.remove(sub.getName()); try { sub.getSendLock(); @@ -559,7 +559,7 @@ public class ServerSession extends Session public void commit() { _transaction.commit(); - + _txnCommits.incrementAndGet(); _txnStarts.incrementAndGet(); decrementOutstandingTxnsIfNecessary(); @@ -568,13 +568,13 @@ public class ServerSession extends Session public void rollback() { _transaction.rollback(); - + _txnRejects.incrementAndGet(); _txnStarts.incrementAndGet(); decrementOutstandingTxnsIfNecessary(); } - + private void incrementOutstandingTxnsIfNecessary() { if(isTransactional()) @@ -584,7 +584,7 @@ public class ServerSession extends Session _txnCount.compareAndSet(0,1); } } - + private void decrementOutstandingTxnsIfNecessary() { if(isTransactional()) @@ -625,7 +625,7 @@ public class ServerSession extends Session { return _txnCount.get(); } - + public Principal getAuthorizedPrincipal() { return getConnection().getAuthorizedPrincipal(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java index 7617544451..c568ae67aa 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/ServerTransaction.java @@ -20,13 +20,12 @@ */ package org.apache.qpid.server.txn; +import java.util.Collection; +import java.util.List; import org.apache.qpid.server.message.EnqueableMessage; import org.apache.qpid.server.queue.BaseQueue; import org.apache.qpid.server.queue.QueueEntry; -import java.util.Collection; -import java.util.List; - /** * The ServerTransaction interface allows a set enqueue/dequeue operations to be diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java index 2ef110641e..489b985222 100755 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java @@ -33,6 +33,7 @@ import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.protocol.v1_0.LinkRegistry; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; @@ -96,6 +97,8 @@ public interface VirtualHost extends DurableConfigurationStore.Source, VirtualHo void removeBrokerConnection(BrokerLink brokerLink); + LinkRegistry getLinkRegistry(String remoteContainerId); + ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask); State getState(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java index 530be46d70..d4f3b11a8c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java @@ -47,6 +47,7 @@ import org.apache.qpid.server.logging.messages.VirtualHostMessages; import org.apache.qpid.server.logging.subjects.MessageStoreLogSubject; import org.apache.qpid.server.management.AMQManagedObject; import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.protocol.v1_0.LinkRegistry; import org.apache.qpid.server.protocol.AMQConnectionModel; import org.apache.qpid.server.protocol.AMQSessionModel; import org.apache.qpid.server.queue.AMQQueue; @@ -67,7 +68,8 @@ import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory; import javax.management.JMException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; - +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.UUID; @@ -126,6 +128,8 @@ public class VirtualHostImpl implements VirtualHost private StatisticsCounter _messagesDelivered, _dataDelivered, _messagesReceived, _dataReceived; + private final Map<String, LinkRegistry> _linkRegistry = new HashMap<String, LinkRegistry>(); + public VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig) throws Exception { if (hostConfig == null) @@ -673,6 +677,17 @@ public class VirtualHostImpl implements VirtualHost } } + public synchronized LinkRegistry getLinkRegistry(String remoteContainerId) + { + LinkRegistry linkRegistry = _linkRegistry.get(remoteContainerId); + if(linkRegistry == null) + { + linkRegistry = new LinkRegistry(); + _linkRegistry.put(remoteContainerId, linkRegistry); + } + return linkRegistry; + } + public ConfigStore getConfigStore() { return getApplicationRegistry().getConfigStore(); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java index db37cc0965..96c67941f9 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/InternalTestProtocolSession.java @@ -34,6 +34,7 @@ import org.apache.qpid.server.registry.ApplicationRegistry; import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal; import org.apache.qpid.server.subscription.ClientDeliveryMethod; import org.apache.qpid.server.subscription.Subscription; +import org.apache.qpid.server.subscription.SubscriptionImpl; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.transport.TestNetworkConnection; @@ -239,12 +240,12 @@ public class InternalTestProtocolSession extends AMQProtocolEngine implements Pr _channelDelivers.put(_channelId, consumers); } - LinkedList<DeliveryPair> consumerDelivers = consumers.get(sub.getConsumerTag()); + LinkedList<DeliveryPair> consumerDelivers = consumers.get(((SubscriptionImpl)sub).getConsumerTag()); if (consumerDelivers == null) { consumerDelivers = new LinkedList<DeliveryPair>(); - consumers.put(sub.getConsumerTag(), consumerDelivers); + consumers.put(((SubscriptionImpl)sub).getConsumerTag(), consumerDelivers); } consumerDelivers.add(new DeliveryPair(deliveryTag, (AMQMessage)entry.getMessage())); diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java index d8b5cd02cf..6081be8efd 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/MultiVersionProtocolEngineFactoryTest.java @@ -35,6 +35,7 @@ import java.util.Set; public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase { + protected void setUp() throws Exception { super.setUp(); @@ -93,7 +94,20 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase (byte) 0, (byte) 10 }; - + + + private static final byte[] AMQP_1_0_0_HEADER = + new byte[] { + (byte)'A', + (byte)'M', + (byte)'Q', + (byte)'P', + (byte) 0, + (byte) 1, + (byte) 0, + (byte) 0 + }; + private byte[] getAmqpHeader(final AmqpProtocolVersion version) { switch(version) @@ -106,6 +120,8 @@ public class MultiVersionProtocolEngineFactoryTest extends QpidTestCase return AMQP_0_9_1_HEADER; case v0_10: return AMQP_0_10_HEADER; + case v1_0_0: + return AMQP_1_0_0_HEADER; default: fail("unknown AMQP version, appropriate header must be added for new protocol version"); return null; diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java index ba0a715001..0e2437978c 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticatorTest.java @@ -29,6 +29,7 @@ import org.apache.qpid.server.security.auth.manager.AuthenticationManager; import javax.management.remote.JMXPrincipal; import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import java.util.Collections; @@ -254,6 +255,11 @@ public class RMIPasswordAuthenticatorTest extends TestCase return new AuthenticationResult(AuthenticationStatus.CONTINUE); } } + + public CallbackHandler getHandler(String mechanism) + { + return null; + } }; } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java index 1d6ccfbbc2..5ba9c0c015 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/subscription/MockSubscription.java @@ -277,6 +277,10 @@ public class MockSubscription implements Subscription return false; } + public void queueEmpty() throws AMQException + { + } + public void setActive(final boolean isActive) { _isActive = isActive; diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java index f27dc33dc3..91174c5d10 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/virtualhost/MockVirtualHost.java @@ -33,6 +33,7 @@ import org.apache.qpid.server.exchange.ExchangeFactory; import org.apache.qpid.server.exchange.ExchangeRegistry; import org.apache.qpid.server.federation.BrokerLink; import org.apache.qpid.server.management.ManagedObject; +import org.apache.qpid.server.protocol.v1_0.LinkRegistry; import org.apache.qpid.server.queue.QueueRegistry; import org.apache.qpid.server.registry.IApplicationRegistry; import org.apache.qpid.server.security.SecurityManager; @@ -171,6 +172,11 @@ public class MockVirtualHost implements VirtualHost } + public LinkRegistry getLinkRegistry(String remoteContainerId) + { + return null; + } + public ScheduledFuture<?> scheduleTask(long delay, Runnable timeoutTask) { return null; diff --git a/qpid/java/build.deps b/qpid/java/build.deps index e60bc3ee93..a376052a94 100644 --- a/qpid/java/build.deps +++ b/qpid/java/build.deps @@ -53,6 +53,8 @@ commons-configuration.libs = ${commons-beanutils-core} ${commons-digester} \ common.libs=${slf4j-api} client.libs=${geronimo-jms} +amqp-1-0-client.libs=${commons-cli} +amqp-1-0-client-jms.libs=${geronimo-jms} tools.libs=${commons-configuration.libs} ${log4j} broker.libs=${commons-cli} ${commons-logging} ${log4j} ${slf4j-log4j} \ ${xalan} ${felix.libs} ${derby-db} ${commons-configuration.libs} diff --git a/qpid/java/build.xml b/qpid/java/build.xml index 6728662d85..088ee8e0be 100644 --- a/qpid/java/build.xml +++ b/qpid/java/build.xml @@ -26,7 +26,7 @@ <findSubProjects name="client-plugins" dir="client-plugins"/> <findSubProjects name="management" dir="management" excludes="common,example"/> - <property name="modules.core" value="common management/common broker client tools"/> + <property name="modules.core" value="common management/common amqp-1-0-common broker client amqp-1-0-client amqp-1-0-client-jms tools"/> <property name="modules.examples" value="client/example management/example"/> <property name="modules.tests" value="systests"/> <property name="modules.management" value="${management}"/> diff --git a/qpid/java/systests/build.xml b/qpid/java/systests/build.xml index 8f56eb21f1..6adce705cd 100644 --- a/qpid/java/systests/build.xml +++ b/qpid/java/systests/build.xml @@ -27,7 +27,7 @@ nn - or more contributor license agreements. See the NOTICE file </and> </condition> - <property name="module.depends" value="client management/common broker broker/test common common/test jca ${systests.optional.depends}"/> + <property name="module.depends" value="client management/common broker broker/test common amqp-1-0-common common/test jca ${systests.optional.depends}"/> <property name="module.test.src" location="src/main/java"/> <property name="module.test.excludes" value="**/DropInTest.java,**/TestClientControlledTest.java"/> diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java index c42bb3b1fa..0e3a658e32 100644 --- a/qpid/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java +++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/SupportedProtocolVersionsTest.java @@ -77,6 +77,7 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase public void testDisabling010() throws Exception { //disable 0-10 support + setConfigurationProperty("connector.amqp10enabled", "false"); setConfigurationProperty("connector.amqp010enabled", "false"); super.setUp(); @@ -92,6 +93,7 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase public void testDisabling091and010() throws Exception { //disable 0-91 and 0-10 support + setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false"); setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, "false"); @@ -111,6 +113,7 @@ public class SupportedProtocolVersionsTest extends QpidBrokerTestCase setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP09ENABLED, "false"); setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP091ENABLED, "false"); setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP010ENABLED, "false"); + setConfigurationProperty(ServerConfiguration.CONNECTOR_AMQP10ENABLED, "false"); super.setUp(); diff --git a/qpid/java/test-profiles/java-bdb-spawn.0-8.testprofile b/qpid/java/test-profiles/java-bdb-spawn.0-8.testprofile index 08da12c44c..62c9385835 100644 --- a/qpid/java/test-profiles/java-bdb-spawn.0-8.testprofile +++ b/qpid/java/test-profiles/java-bdb-spawn.0-8.testprofile @@ -27,7 +27,7 @@ messagestorefactory.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessag profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes broker.clean.between.tests=true broker.persistent=true -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT broker.version=v0_8 # # Do not enable. Allow client to attempt 0-10 and negotiate downwards diff --git a/qpid/java/test-profiles/java-bdb-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-bdb-spawn.0-9-1.testprofile index 240ade18c0..cfc2a12dde 100644 --- a/qpid/java/test-profiles/java-bdb-spawn.0-9-1.testprofile +++ b/qpid/java/test-profiles/java-bdb-spawn.0-9-1.testprofile @@ -27,7 +27,7 @@ messagestorefactory.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessag profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes broker.clean.between.tests=true broker.persistent=true -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT broker.version=v0_9_1 # # Do not enable. Allow client to attempt 0-10 and negotiate downwards diff --git a/qpid/java/test-profiles/java-bdb-spawn.0-9.testprofile b/qpid/java/test-profiles/java-bdb-spawn.0-9.testprofile index 5e3ca0b470..9cfa25eb9a 100644 --- a/qpid/java/test-profiles/java-bdb-spawn.0-9.testprofile +++ b/qpid/java/test-profiles/java-bdb-spawn.0-9.testprofile @@ -27,7 +27,7 @@ messagestorefactory.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessag profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes broker.clean.between.tests=true broker.persistent=true -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT broker.version=v0_9 # # Do not enable. Allow client to attempt 0-10 and negotiate downwards diff --git a/qpid/java/test-profiles/java-bdb.0-8.testprofile b/qpid/java/test-profiles/java-bdb.0-8.testprofile index 7590f7b858..76c3ea0b72 100644 --- a/qpid/java/test-profiles/java-bdb.0-8.testprofile +++ b/qpid/java/test-profiles/java-bdb.0-8.testprofile @@ -28,7 +28,7 @@ messagestorefactory.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessag profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes broker.clean.between.tests=true broker.persistent=true -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT broker.version=v0_8 # # Do not enable. Allow client to attempt 0-10 and negotiate downwards diff --git a/qpid/java/test-profiles/java-bdb.0-9-1.testprofile b/qpid/java/test-profiles/java-bdb.0-9-1.testprofile index 1543bcd0ad..afc5f7bfd1 100644 --- a/qpid/java/test-profiles/java-bdb.0-9-1.testprofile +++ b/qpid/java/test-profiles/java-bdb.0-9-1.testprofile @@ -28,7 +28,7 @@ messagestorefactory.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessag profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes broker.clean.between.tests=true broker.persistent=true -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT broker.version=v0_9_1 # # Do not enable. Allow client to attempt 0-10 and negotiate downwards diff --git a/qpid/java/test-profiles/java-bdb.0-9.testprofile b/qpid/java/test-profiles/java-bdb.0-9.testprofile index 5a6a6536b4..76bde0defc 100644 --- a/qpid/java/test-profiles/java-bdb.0-9.testprofile +++ b/qpid/java/test-profiles/java-bdb.0-9.testprofile @@ -28,7 +28,7 @@ messagestorefactory.class.name=org.apache.qpid.server.store.berkeleydb.BDBMessag profile.excludes=JavaExcludes JavaPersistentExcludes XAExcludes JavaPre010Excludes JavaBDBExcludes broker.clean.between.tests=true broker.persistent=true -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT broker.version=v0_9 # # Do not enable. Allow client to attempt 0-10 and negotiate downwards diff --git a/qpid/java/test-profiles/java-dby-spawn.0-8.testprofile b/qpid/java/test-profiles/java-dby-spawn.0-8.testprofile index 27b4b30d0f..9d421f706e 100644 --- a/qpid/java/test-profiles/java-dby-spawn.0-8.testprofile +++ b/qpid/java/test-profiles/java-dby-spawn.0-8.testprofile @@ -23,7 +23,7 @@ broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FIL broker.ready=BRK-1004 broker.stopped=Exception broker.config=build/etc/config-systests-derby.xml -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes broker.clean.between.tests=true diff --git a/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile index 8a9ea0b55e..3038dd324e 100644 --- a/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile +++ b/qpid/java/test-profiles/java-dby-spawn.0-9-1.testprofile @@ -23,7 +23,7 @@ broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FIL broker.ready=BRK-1004 broker.stopped=Exception broker.config=build/etc/config-systests-derby.xml -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes broker.clean.between.tests=true diff --git a/qpid/java/test-profiles/java-dby-spawn.0-9.testprofile b/qpid/java/test-profiles/java-dby-spawn.0-9.testprofile index 1f6c2877da..6007105097 100644 --- a/qpid/java/test-profiles/java-dby-spawn.0-9.testprofile +++ b/qpid/java/test-profiles/java-dby-spawn.0-9.testprofile @@ -23,7 +23,7 @@ broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FIL broker.ready=BRK-1004 broker.stopped=Exception broker.config=build/etc/config-systests-derby.xml -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes broker.clean.between.tests=true diff --git a/qpid/java/test-profiles/java-dby.0-8.testprofile b/qpid/java/test-profiles/java-dby.0-8.testprofile index 68227e87c5..c841c69922 100644 --- a/qpid/java/test-profiles/java-dby.0-8.testprofile +++ b/qpid/java/test-profiles/java-dby.0-8.testprofile @@ -24,7 +24,7 @@ broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FIL broker.ready=BRK-1004 broker.stopped=Exception broker.config=build/etc/config-systests-derby.xml -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes broker.clean.between.tests=true diff --git a/qpid/java/test-profiles/java-dby.0-9-1.testprofile b/qpid/java/test-profiles/java-dby.0-9-1.testprofile index 2a3644d39a..fa01010d52 100644 --- a/qpid/java/test-profiles/java-dby.0-9-1.testprofile +++ b/qpid/java/test-profiles/java-dby.0-9-1.testprofile @@ -24,7 +24,7 @@ broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FIL broker.ready=BRK-1004 broker.stopped=Exception broker.config=build/etc/config-systests-derby.xml -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes broker.clean.between.tests=true diff --git a/qpid/java/test-profiles/java-dby.0-9.testprofile b/qpid/java/test-profiles/java-dby.0-9.testprofile index 7fd70665c2..d343185591 100644 --- a/qpid/java/test-profiles/java-dby.0-9.testprofile +++ b/qpid/java/test-profiles/java-dby.0-9.testprofile @@ -24,7 +24,7 @@ broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FIL broker.ready=BRK-1004 broker.stopped=Exception broker.config=build/etc/config-systests-derby.xml -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT messagestorefactory.class.name=org.apache.qpid.server.store.derby.DerbyMessageStoreFactory profile.excludes=JavaPersistentExcludes JavaDerbyExcludes XAExcludes JavaPre010Excludes broker.clean.between.tests=true diff --git a/qpid/java/test-profiles/java-mms-spawn.0-8.testprofile b/qpid/java/test-profiles/java-mms-spawn.0-8.testprofile index b075890e58..1b6b6f28a3 100644 --- a/qpid/java/test-profiles/java-mms-spawn.0-8.testprofile +++ b/qpid/java/test-profiles/java-mms-spawn.0-8.testprofile @@ -22,7 +22,7 @@ broker.type=spawned broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l test-profiles/log4j-test.xml broker.ready=BRK-1004 broker.stopped=Exception -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT # # Do not enable. Allow client to attempt 0-10 and negotiate downwards # diff --git a/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile b/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile index 7f80dc743a..e87ae2b204 100644 --- a/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile +++ b/qpid/java/test-profiles/java-mms-spawn.0-9-1.testprofile @@ -22,7 +22,7 @@ broker.type=spawned broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l test-profiles/log4j-test.xml broker.ready=BRK-1004 broker.stopped=Exception -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT # # Do not enable. Allow client to attempt 0-10 and negotiate downwards # diff --git a/qpid/java/test-profiles/java-mms-spawn.0-9.testprofile b/qpid/java/test-profiles/java-mms-spawn.0-9.testprofile index 57e670ec31..2a9430242e 100644 --- a/qpid/java/test-profiles/java-mms-spawn.0-9.testprofile +++ b/qpid/java/test-profiles/java-mms-spawn.0-9.testprofile @@ -22,7 +22,7 @@ broker.type=spawned broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l test-profiles/log4j-test.xml broker.ready=BRK-1004 broker.stopped=Exception -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT # # Do not enable. Allow client to attempt 0-10 and negotiate downwards # diff --git a/qpid/java/test-profiles/java-mms.0-8.testprofile b/qpid/java/test-profiles/java-mms.0-8.testprofile index d7ef32ae3b..1f02a49b28 100644 --- a/qpid/java/test-profiles/java-mms.0-8.testprofile +++ b/qpid/java/test-profiles/java-mms.0-8.testprofile @@ -23,7 +23,7 @@ broker.type=internal broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l test-profiles/log4j-test.xml broker.ready=BRK-1004 broker.stopped=Exception -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT --exclude-0-9 @PORT --exclude-0-9 @SSL_PORT # # Do not enable. Allow client to attempt 0-10 and negotiate downwards # diff --git a/qpid/java/test-profiles/java-mms.0-9-1.testprofile b/qpid/java/test-profiles/java-mms.0-9-1.testprofile index a2dc90bc63..ae707f025d 100644 --- a/qpid/java/test-profiles/java-mms.0-9-1.testprofile +++ b/qpid/java/test-profiles/java-mms.0-9-1.testprofile @@ -23,7 +23,7 @@ broker.type=internal broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l test-profiles/log4j-test.xml broker.ready=BRK-1004 broker.stopped=Exception -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT # # Do not enable. Allow client to attempt 0-10 and negotiate downwards # diff --git a/qpid/java/test-profiles/java-mms.0-9.testprofile b/qpid/java/test-profiles/java-mms.0-9.testprofile index 398a9ac4d0..8f372299ea 100644 --- a/qpid/java/test-profiles/java-mms.0-9.testprofile +++ b/qpid/java/test-profiles/java-mms.0-9.testprofile @@ -23,7 +23,7 @@ broker.type=internal broker.command=build/bin/qpid-server -p @PORT -m @MPORT @EXCLUDES -c @CONFIG_FILE -l test-profiles/log4j-test.xml broker.ready=BRK-1004 broker.stopped=Exception -broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT +broker.protocol.excludes=--exclude-0-10 @PORT --exclude-0-10 @SSL_PORT --exclude-1-0 @PORT --exclude-1-0 @SSL_PORT --exclude-0-9-1 @PORT --exclude-0-9-1 @SSL_PORT # # Do not enable. Allow client to attempt 0-10 and negotiate downwards # |
