You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2015/05/19 19:04:58 UTC
qpid-jms git commit: QPIDJMS-52,
QPIDJMS-53: support the charset param in content-type,
and treat messages with Data sections and common textual content-types as
TextMessage rahter than BytesMessage
Repository: qpid-jms
Updated Branches:
refs/heads/master 3637ec999 -> 021867fd1
QPIDJMS-52, QPIDJMS-53: support the charset param in content-type, and treat messages with Data sections and common textual content-types as TextMessage rahter than BytesMessage
Project: http://git-wip-us.apache.org/repos/asf/qpid-jms/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-jms/commit/021867fd
Tree: http://git-wip-us.apache.org/repos/asf/qpid-jms/tree/021867fd
Diff: http://git-wip-us.apache.org/repos/asf/qpid-jms/diff/021867fd
Branch: refs/heads/master
Commit: 021867fd17f835f3d665f35d3b94abd6d51c9f5c
Parents: 3637ec9
Author: Robert Gemmell <ro...@apache.org>
Authored: Tue May 19 17:58:29 2015 +0100
Committer: Robert Gemmell <ro...@apache.org>
Committed: Tue May 19 17:58:29 2015 +0100
----------------------------------------------------------------------
.../amqp/message/AmqpJmsMessageBuilder.java | 49 ++--
.../amqp/message/AmqpJmsTextMessageFacade.java | 25 +-
.../amqp/message/AmqpMessageSupport.java | 5 -
.../qpid/jms/util/ContentTypeSupport.java | 142 ++++++++++++
.../jms/util/InvalidContentTypeException.java | 26 +++
.../amqp/message/AmqpJmsMessageBuilderTest.java | 109 ++++++++-
.../message/AmqpJmsMessageTypesTestCase.java | 4 +-
.../qpid/jms/util/ContentTypeSupportTest.java | 229 +++++++++++++++++++
8 files changed, 545 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilder.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilder.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilder.java
index eb66b03..713a7d8 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilder.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilder.java
@@ -25,10 +25,11 @@ import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_S
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.JMS_TEXT_MESSAGE;
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.OCTET_STREAM_CONTENT_TYPE;
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE;
-import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.TEXT_PLAIN_CONTENT_TYPE;
import static org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport.isContentType;
import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import org.apache.qpid.jms.message.JmsBytesMessage;
import org.apache.qpid.jms.message.JmsMapMessage;
@@ -37,6 +38,8 @@ import org.apache.qpid.jms.message.JmsObjectMessage;
import org.apache.qpid.jms.message.JmsStreamMessage;
import org.apache.qpid.jms.message.JmsTextMessage;
import org.apache.qpid.jms.provider.amqp.AmqpConsumer;
+import org.apache.qpid.jms.util.ContentTypeSupport;
+import org.apache.qpid.jms.util.InvalidContentTypeException;
import org.apache.qpid.proton.amqp.Binary;
import org.apache.qpid.proton.amqp.messaging.AmqpSequence;
import org.apache.qpid.proton.amqp.messaging.AmqpValue;
@@ -91,7 +94,7 @@ public class AmqpJmsMessageBuilder {
case JMS_BYTES_MESSAGE:
return createBytesMessage(consumer, message);
case JMS_TEXT_MESSAGE:
- return createTextMessage(consumer, message);
+ return createTextMessage(consumer, message, StandardCharsets.UTF_8);
case JMS_MAP_MESSAGE:
return createMapMessage(consumer, message);
case JMS_STREAM_MESSAGE:
@@ -110,32 +113,36 @@ public class AmqpJmsMessageBuilder {
Section body = message.getBody();
if (body == null) {
- // TODO: accept textual content types other than strictly "text/plain"
- if (isContentType(TEXT_PLAIN_CONTENT_TYPE, message)) {
- return createTextMessage(consumer, message);
- } else if (isContentType(SERIALIZED_JAVA_OBJECT_CONTENT_TYPE, message)) {
+ if (isContentType(SERIALIZED_JAVA_OBJECT_CONTENT_TYPE, message)) {
return createObjectMessage(consumer, message);
} else if (isContentType(OCTET_STREAM_CONTENT_TYPE, message) || isContentType(null, message)) {
return createBytesMessage(consumer, message);
} else {
- return createMessage(consumer, message);
+ Charset charset = getCharsetForTextualContent(message.getContentType());
+ if (charset != null) {
+ return createTextMessage(consumer, message, charset);
+ } else {
+ return createMessage(consumer, message);
+ }
}
} else if (body instanceof Data) {
- // TODO: accept textual content types other than strictly "text/plain"
- if (isContentType(TEXT_PLAIN_CONTENT_TYPE, message)) {
- return createTextMessage(consumer, message);
- } else if (isContentType(OCTET_STREAM_CONTENT_TYPE, message) || isContentType(null, message)) {
+ if (isContentType(OCTET_STREAM_CONTENT_TYPE, message) || isContentType(null, message)) {
return createBytesMessage(consumer, message);
} else if (isContentType(SERIALIZED_JAVA_OBJECT_CONTENT_TYPE, message)) {
return createObjectMessage(consumer, message);
} else {
- return createBytesMessage(consumer, message);
+ Charset charset = getCharsetForTextualContent(message.getContentType());
+ if (charset != null) {
+ return createTextMessage(consumer, message, charset);
+ } else {
+ return createBytesMessage(consumer, message);
+ }
}
} else if (body instanceof AmqpValue) {
Object value = ((AmqpValue) body).getValue();
if (value == null || value instanceof String) {
- return createTextMessage(consumer, message);
+ return createTextMessage(consumer, message, StandardCharsets.UTF_8);
} else if (value instanceof Binary) {
return createBytesMessage(consumer, message);
} else {
@@ -160,8 +167,8 @@ public class AmqpJmsMessageBuilder {
return new JmsMapMessage(new AmqpJmsMapMessageFacade(consumer, message));
}
- private static JmsTextMessage createTextMessage(AmqpConsumer consumer, Message message) {
- return new JmsTextMessage(new AmqpJmsTextMessageFacade(consumer, message));
+ private static JmsTextMessage createTextMessage(AmqpConsumer consumer, Message message, Charset charset) {
+ return new JmsTextMessage(new AmqpJmsTextMessageFacade(consumer, message, charset));
}
private static JmsBytesMessage createBytesMessage(AmqpConsumer consumer, Message message) {
@@ -171,4 +178,16 @@ public class AmqpJmsMessageBuilder {
private static JmsMessage createMessage(AmqpConsumer consumer, Message message) {
return new JmsMessage(new AmqpJmsMessageFacade(consumer, message));
}
+
+ /**
+ * @param contentType the contentType of the received message
+ * @return the character set to use, or null if not to treat the message as text
+ */
+ private static Charset getCharsetForTextualContent(String contentType) {
+ try {
+ return ContentTypeSupport.parseContentTypeForTextualCharset(contentType);
+ } catch (InvalidContentTypeException e) {
+ return null;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsTextMessageFacade.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsTextMessageFacade.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsTextMessageFacade.java
index 6a4850e..064c49d 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsTextMessageFacade.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsTextMessageFacade.java
@@ -24,6 +24,7 @@ import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
+import java.nio.charset.StandardCharsets;
import javax.jms.JMSException;
@@ -43,15 +44,7 @@ import org.apache.qpid.proton.message.Message;
*/
public class AmqpJmsTextMessageFacade extends AmqpJmsMessageFacade implements JmsTextMessageFacade {
- private static final String UTF_8 = "UTF-8";
-
- /**
- * Content type, only to be used when message uses a data
- * body section, and not when using an amqp-value body section
- */
- public static final String CONTENT_TYPE = "text/plain";
-
- private final CharsetDecoder decoder = Charset.forName(UTF_8).newDecoder();
+ private final Charset charset;
/**
* Create a new AMQP Message facade ready for sending.
@@ -63,6 +56,7 @@ public class AmqpJmsTextMessageFacade extends AmqpJmsMessageFacade implements Jm
super(connection);
setMessageAnnotation(JMS_MSG_TYPE, JMS_TEXT_MESSAGE);
setText(null);
+ charset = StandardCharsets.UTF_8;
}
/**
@@ -73,9 +67,12 @@ public class AmqpJmsTextMessageFacade extends AmqpJmsMessageFacade implements Jm
* the consumer that received this message.
* @param message
* the incoming Message instance that is being wrapped.
+ * @param charset
+ * the character set to use when decoding the text when the body is a Data section
*/
- public AmqpJmsTextMessageFacade(AmqpConsumer consumer, Message message) {
+ public AmqpJmsTextMessageFacade(AmqpConsumer consumer, Message message, Charset charset) {
super(consumer, message);
+ this.charset = charset;
}
/**
@@ -109,10 +106,10 @@ public class AmqpJmsTextMessageFacade extends AmqpJmsMessageFacade implements Jm
ByteBuffer buf = ByteBuffer.wrap(b.getArray(), b.getArrayOffset(), b.getLength());
try {
- CharBuffer chars = decoder.decode(buf);
+ CharBuffer chars = charset.newDecoder().decode(buf);
return String.valueOf(chars);
} catch (CharacterCodingException e) {
- throw JmsExceptionSupport.create("Cannot decode String in UFT-8", e);
+ throw JmsExceptionSupport.create("Cannot decode String in " + charset.displayName(), e);
}
}
} else if (body instanceof AmqpValue) {
@@ -166,4 +163,8 @@ public class AmqpJmsTextMessageFacade extends AmqpJmsMessageFacade implements Jm
return false;
}
+
+ Charset getCharset() {
+ return charset;
+ }
}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageSupport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageSupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageSupport.java
index 644d50f..d1c3d59 100644
--- a/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageSupport.java
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/provider/amqp/message/AmqpMessageSupport.java
@@ -80,11 +80,6 @@ public final class AmqpMessageSupport {
public static final String JMS_AMQP_TYPED_ENCODING = "JMS_AMQP_TYPED_ENCODING";
/**
- * Content type used to mark Data sections as containing text.
- */
- public static final String TEXT_PLAIN_CONTENT_TYPE = "text/plain";
-
- /**
* Content type used to mark Data sections as containing a serialized java object.
*/
public static final String SERIALIZED_JAVA_OBJECT_CONTENT_TYPE = "application/x-java-serialized-object";
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ContentTypeSupport.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ContentTypeSupport.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ContentTypeSupport.java
new file mode 100644
index 0000000..6a3fff1
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/ContentTypeSupport.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.jms.util;
+
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.StringTokenizer;
+
+public final class ContentTypeSupport {
+
+ private static final String UTF_8 = "UTF-8";
+ private static final String CHARSET = "charset";
+ private static final String TEXT = "text";
+ private static final String APPLICATION = "application";
+ private static final String JAVASCRIPT = "javascript";
+ private static final String XML = "xml";
+ private static final String XML_VARIANT = "+xml";
+ private static final String JSON = "json";
+ private static final String JSON_VARIANT = "+json";
+ private static final String XML_DTD = "xml-dtd";
+ private static final String ECMASCRIPT = "ecmascript";
+
+ /**
+ * @param contentType the contentType of the received message
+ * @return the character set to use, or null if not to treat the message as text
+ * @throws InvalidContentTypeException if the content-type is invalid in some way.
+ */
+ public static Charset parseContentTypeForTextualCharset(final String contentType) throws InvalidContentTypeException {
+ if (contentType == null || contentType.trim().isEmpty()) {
+ throw new InvalidContentTypeException("Content type can't be null or empty");
+ }
+
+ int subTypeSeparator = contentType.indexOf("/");
+ if(subTypeSeparator == -1) {
+ throw new InvalidContentTypeException("Content type has no '/' separator: " + contentType);
+ }
+
+ final String type = contentType.substring(0, subTypeSeparator).toLowerCase().trim();
+
+ String subTypePart = contentType.substring(subTypeSeparator +1).toLowerCase().trim();
+
+ String parameterPart = null;
+ int parameterSeparator = subTypePart.indexOf(";");
+ if(parameterSeparator != -1)
+ {
+ if(parameterSeparator < subTypePart.length() - 1) {
+ parameterPart = contentType.substring(subTypeSeparator + 1).toLowerCase().trim();
+ }
+ subTypePart = subTypePart.substring(0, parameterSeparator).trim();
+ }
+
+ if(subTypePart.isEmpty()) {
+ throw new InvalidContentTypeException("Content type has no subtype after '/'" + contentType);
+ }
+
+ final String subType = subTypePart;
+
+ if(isTextual(type, subType)) {
+ String charset = findCharset(parameterPart);
+ if(charset == null) {
+ charset = UTF_8;
+ }
+
+ if (UTF_8.equals(charset)) {
+ return StandardCharsets.UTF_8;
+ } else {
+ try {
+ return Charset.forName(charset);
+ } catch (IllegalCharsetNameException icne) {
+ throw new InvalidContentTypeException("Illegal charset: " + charset);
+ } catch (UnsupportedCharsetException uce) {
+ throw new InvalidContentTypeException("Unsupported charset: " + charset);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static boolean isTextual(String type, String subType) {
+ if (TEXT.equals(type)) {
+ return true;
+ }
+
+ if (APPLICATION.equals(type)) {
+ if (XML.equals(subType) || JSON.equals(subType) || JAVASCRIPT.equals(subType)
+ || subType.endsWith(XML_VARIANT) || subType.endsWith(JSON_VARIANT)
+ || XML_DTD.equals(subType) || ECMASCRIPT.equals(subType) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static String findCharset(String paramaterPart) {
+ String charset = null;
+
+ if (paramaterPart != null) {
+ StringTokenizer tokenizer = new StringTokenizer(paramaterPart, ";");
+ while (tokenizer.hasMoreTokens()) {
+ String parameter = tokenizer.nextToken().trim();
+ int eqIndex = parameter.indexOf('=');
+ if (eqIndex != -1) {
+ String name = parameter.substring(0, eqIndex);
+ if (CHARSET.equalsIgnoreCase(name.trim())) {
+ String value = unquote(parameter.substring(eqIndex + 1));
+
+ charset = value.toUpperCase();
+ break;
+ }
+ }
+ }
+ }
+
+ return charset;
+ }
+
+ private static String unquote(String s) {
+ if (s.length() > 1 && (s.startsWith("\"") && s.endsWith("\""))) {
+ return s.substring(1, s.length() - 1);
+ } else {
+ return s;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/InvalidContentTypeException.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/InvalidContentTypeException.java b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/InvalidContentTypeException.java
new file mode 100644
index 0000000..1547ca3
--- /dev/null
+++ b/qpid-jms-client/src/main/java/org/apache/qpid/jms/util/InvalidContentTypeException.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.jms.util;
+
+public class InvalidContentTypeException extends Exception {
+
+ private static final long serialVersionUID = -2172537375174014839L;
+
+ public InvalidContentTypeException(String message) {
+ super(message);
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilderTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilderTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilderTest.java
index 569b456..48686da 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilderTest.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageBuilderTest.java
@@ -26,6 +26,8 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -300,15 +302,10 @@ public class AmqpJmsMessageBuilderTest extends QpidJmsTestCase {
assertTrue("Unexpected delegate type: " + delegate, delegate instanceof AmqpSerializedObjectDelegate);
}
- /**
- * Test that a message with no body section, but with the content type set to
- * {@value AmqpMessageSupport#TEXT_PLAIN_CONTENT_TYPE} results in a TextMessage
- * when not otherwise annotated to indicate the type of JMS message it is.
- */
@Test
public void testCreateTextMessageFromNoBodySectionAndContentType() throws Exception {
Message message = Proton.message();
- message.setContentType(AmqpMessageSupport.TEXT_PLAIN_CONTENT_TYPE);
+ message.setContentType("text/plain");
JmsMessage jmsMessage = AmqpJmsMessageBuilder.createJmsMessage(mockConsumer, message);
assertNotNull("Message should not be null", jmsMessage);
@@ -427,16 +424,103 @@ public class AmqpJmsMessageBuilderTest extends QpidJmsTestCase {
}
/**
- * Test that receiving a data body containing nothing, but with the content type set to
- * {@value AmqpMessageSupport#TEXT_PLAIN_CONTENT_TYPE} results in a TextMessage when
- * not otherwise annotated to indicate the type of JMS message it is.
+ * Test that receiving a Data body section with the content type set to
+ * 'text/plain' results in a TextMessage when not otherwise annotated to
+ * indicate the type of JMS message it is.
*/
@Test
- public void testCreateTextMessageFromDataWithContentTypeAndEmptyBinary() throws Exception {
+ public void testCreateTextMessageFromDataWithContentTypeTextPlain() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/plain;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/plain;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/plain;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/plain", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeTextJson() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/json;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/json;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/json;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/json", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeTextHtml() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/html;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/html;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/html;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/html", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeTextFoo() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/foo;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/foo;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/foo;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("text/foo", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationJson() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/json;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/json;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/json;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/json", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationJsonVariant() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+json;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+json;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+json;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+json", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationJavascript() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/javascript;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/javascript;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/javascript;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/javascript", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationEcmascript() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/ecmascript;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/ecmascript;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/ecmascript;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/ecmascript", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationXml() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationXmlVariant() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+xml;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+xml;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+xml;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/something+xml", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testCreateTextMessageFromDataWithContentTypeApplicationXmlDtd() throws Exception {
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml-dtd;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml-dtd;charset=us-ascii", StandardCharsets.US_ASCII);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml-dtd;charset=utf-8", StandardCharsets.UTF_8);
+ doCreateTextMessageFromDataWithContentTypeTestImpl("application/xml-dtd", StandardCharsets.UTF_8);
+ }
+
+ private void doCreateTextMessageFromDataWithContentTypeTestImpl(String contentType, Charset expectedCharset) throws IOException {
Message message = Proton.message();
Binary binary = new Binary(new byte[0]);
message.setBody(new Data(binary));
- message.setContentType(AmqpMessageSupport.TEXT_PLAIN_CONTENT_TYPE);
+ message.setContentType(contentType);
JmsMessage jmsMessage = AmqpJmsMessageBuilder.createJmsMessage(mockConsumer, message);
assertNotNull("Message should not be null", jmsMessage);
@@ -445,6 +529,9 @@ public class AmqpJmsMessageBuilderTest extends QpidJmsTestCase {
JmsMessageFacade facade = jmsMessage.getFacade();
assertNotNull("Facade should not be null", facade);
assertEquals("Unexpected facade class type", AmqpJmsTextMessageFacade.class, facade.getClass());
+
+ AmqpJmsTextMessageFacade textFacade = (AmqpJmsTextMessageFacade) facade;
+ assertEquals("Unexpected character set", expectedCharset, textFacade.getCharset());
}
// --------- AmqpValue Body Section ---------
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java
index 6324b75..3d5d197 100644
--- a/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/provider/amqp/message/AmqpJmsMessageTypesTestCase.java
@@ -16,6 +16,8 @@
*/
package org.apache.qpid.jms.provider.amqp.message;
+import java.nio.charset.StandardCharsets;
+
import org.apache.qpid.jms.JmsDestination;
import org.apache.qpid.jms.JmsTopic;
import org.apache.qpid.jms.provider.amqp.AmqpConnection;
@@ -51,7 +53,7 @@ public class AmqpJmsMessageTypesTestCase extends QpidJmsTestCase {
}
protected AmqpJmsTextMessageFacade createReceivedTextMessageFacade(AmqpConsumer amqpConsumer, Message message) {
- return new AmqpJmsTextMessageFacade(amqpConsumer, message);
+ return new AmqpJmsTextMessageFacade(amqpConsumer, message, StandardCharsets.UTF_8);
}
protected AmqpJmsBytesMessageFacade createNewBytesMessageFacade() {
http://git-wip-us.apache.org/repos/asf/qpid-jms/blob/021867fd/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ContentTypeSupportTest.java
----------------------------------------------------------------------
diff --git a/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ContentTypeSupportTest.java b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ContentTypeSupportTest.java
new file mode 100644
index 0000000..d1f44b0
--- /dev/null
+++ b/qpid-jms-client/src/test/java/org/apache/qpid/jms/util/ContentTypeSupportTest.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.qpid.jms.util;
+
+import static org.junit.Assert.*;
+
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.qpid.jms.provider.amqp.message.AmqpMessageSupport;
+import org.junit.Test;
+
+public class ContentTypeSupportTest {
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeWithOnlyType() throws Exception {
+ doParseContentTypeTestImpl("type", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeEndsWithSlash() throws Exception {
+ doParseContentTypeTestImpl("type/", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeMissingSubtype() throws Exception {
+ doParseContentTypeTestImpl("type/;", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeEmptyString() throws Exception {
+ doParseContentTypeTestImpl("", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeNullString() throws Exception {
+ doParseContentTypeTestImpl(null, null);
+ }
+
+ @Test
+ public void testParseContentTypeNoParamsAfterSeparatorNonTextual() throws Exception {
+ // Expect null as this is not a textual type
+ doParseContentTypeTestImpl("type/subtype;", null);
+ }
+
+ @Test
+ public void testParseContentTypeNoParamsAfterSeparatorTextualType() throws Exception {
+ doParseContentTypeTestImpl("text/plain;", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeEmptyParamsAfterSeparator() throws Exception {
+ doParseContentTypeTestImpl("text/plain;;", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeNoParams() throws Exception {
+ doParseContentTypeTestImpl("text/plain", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithCharsetUtf8() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=utf-8", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithCharsetAscii() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=us-ascii", StandardCharsets.US_ASCII);
+ }
+
+ @Test
+ public void testParseContentTypeWithMultipleParams() throws Exception {
+ doParseContentTypeTestImpl("text/plain; param=value; charset=us-ascii", StandardCharsets.US_ASCII);
+ }
+
+ @Test
+ public void testParseContentTypeWithCharsetQuoted() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=\"us-ascii\"", StandardCharsets.US_ASCII);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeWithCharsetQuotedEmpty() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=\"\"", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeWithCharsetQuoteNotClosed() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=\"unclosed", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeWithCharsetQuoteNotClosedEmpty() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=\"", null);
+ }
+
+ @Test (expected = InvalidContentTypeException.class)
+ public void testParseContentTypeWithNoCharsetValue() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=", null);
+ }
+
+ @Test
+ public void testParseContentTypeWithTextPlain() throws Exception {
+ doParseContentTypeTestImpl("text/plain;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("text/plain;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("text/plain;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("text/plain", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithTextJson() throws Exception {
+ doParseContentTypeTestImpl("text/json;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("text/json;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("text/json;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("text/json", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithTextHtml() throws Exception {
+ doParseContentTypeTestImpl("text/html;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("text/html;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("text/html;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("text/html", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithTextFoo() throws Exception {
+ doParseContentTypeTestImpl("text/foo;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("text/foo;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("text/foo;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("text/foo", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationJson() throws Exception {
+ doParseContentTypeTestImpl("application/json;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/json;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/json;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/json", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationJsonVariant() throws Exception {
+ doParseContentTypeTestImpl("application/something+json;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/something+json;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/something+json;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/something+json", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationJavascript() throws Exception {
+ doParseContentTypeTestImpl("application/javascript;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/javascript;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/javascript;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/javascript", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationEcmascript() throws Exception {
+ doParseContentTypeTestImpl("application/ecmascript;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/ecmascript;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/ecmascript;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/ecmascript", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationXml() throws Exception {
+ doParseContentTypeTestImpl("application/xml;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/xml;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/xml;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/xml", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationXmlVariant() throws Exception {
+ doParseContentTypeTestImpl("application/something+xml;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/something+xml;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/something+xml;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/something+xml", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationXmlDtd() throws Exception {
+ doParseContentTypeTestImpl("application/xml-dtd;charset=iso-8859-1", StandardCharsets.ISO_8859_1);
+ doParseContentTypeTestImpl("application/xml-dtd;charset=us-ascii", StandardCharsets.US_ASCII);
+ doParseContentTypeTestImpl("application/xml-dtd;charset=utf-8", StandardCharsets.UTF_8);
+ doParseContentTypeTestImpl("application/xml-dtd", StandardCharsets.UTF_8);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationOtherNotTextual() throws Exception {
+ // Expect null as this is not a textual type
+ doParseContentTypeTestImpl("application/other", null);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationOctetStream() throws Exception {
+ // Expect null as this is not a textual type
+ doParseContentTypeTestImpl(AmqpMessageSupport.OCTET_STREAM_CONTENT_TYPE, null);
+ }
+
+ @Test
+ public void testParseContentTypeWithApplicationJavaSerialized() throws Exception {
+ // Expect null as this is not a textual type
+ doParseContentTypeTestImpl(AmqpMessageSupport.SERIALIZED_JAVA_OBJECT_CONTENT_TYPE, null);
+ }
+
+ private void doParseContentTypeTestImpl(String contentType, Charset expected) throws InvalidContentTypeException {
+ Charset charset = ContentTypeSupport.parseContentTypeForTextualCharset(contentType);
+ if (expected == null) {
+ assertNull("Expected no charset, but got:" + charset, charset);
+ } else {
+ assertEquals("Charset not as expected", expected, charset);
+ }
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org