001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.client.message;
022
023 import java.util.HashMap;
024 import java.util.List;
025 import java.util.Map;
026 import java.nio.ByteBuffer;
027
028 import javax.jms.JMSException;
029
030 import org.apache.qpid.AMQException;
031 import org.apache.qpid.framing.AMQShortString;
032 import org.apache.qpid.framing.BasicContentHeaderProperties;
033 import org.apache.qpid.framing.ContentHeaderBody;
034 import org.apache.qpid.transport.Struct;
035 import org.apache.qpid.transport.MessageProperties;
036 import org.apache.qpid.transport.MessageTransfer;
037 import org.apache.qpid.transport.DeliveryProperties;
038 import org.slf4j.Logger;
039 import org.slf4j.LoggerFactory;
040
041 public class MessageFactoryRegistry
042 {
043 /**
044 * This class logger
045 */
046 protected final Logger _logger = LoggerFactory.getLogger(getClass());
047
048 private final Map<String, MessageFactory> _mimeStringToFactoryMap = new HashMap<String, MessageFactory>();
049 private final Map<AMQShortString, MessageFactory> _mimeShortStringToFactoryMap =
050 new HashMap<AMQShortString, MessageFactory>();
051
052 /**
053 * Construct a new registry with the default message factories registered
054 *
055 * @return a message factory registry
056 */
057 public static MessageFactoryRegistry newDefaultRegistry()
058 {
059 MessageFactoryRegistry mf = new MessageFactoryRegistry();
060 mf.registerFactory(JMSMapMessage.MIME_TYPE, new JMSMapMessageFactory());
061 mf.registerFactory("text/plain", new JMSTextMessageFactory());
062 mf.registerFactory("text/xml", new JMSTextMessageFactory());
063 mf.registerFactory(JMSBytesMessage.MIME_TYPE, new JMSBytesMessageFactory());
064 mf.registerFactory(JMSObjectMessage.MIME_TYPE, new JMSObjectMessageFactory());
065 mf.registerFactory(JMSStreamMessage.MIME_TYPE, new JMSStreamMessageFactory());
066 mf.registerFactory(null, new JMSBytesMessageFactory());
067
068 return mf;
069 }
070
071
072 public void registerFactory(String mimeType, MessageFactory mf)
073 {
074 if (mf == null)
075 {
076 throw new IllegalArgumentException("Message factory must not be null");
077 }
078
079 _mimeStringToFactoryMap.put(mimeType, mf);
080 _mimeShortStringToFactoryMap.put(new AMQShortString(mimeType), mf);
081 }
082
083 public MessageFactory deregisterFactory(String mimeType)
084 {
085 _mimeShortStringToFactoryMap.remove(new AMQShortString(mimeType));
086
087 return _mimeStringToFactoryMap.remove(mimeType);
088 }
089
090 /**
091 * Create a message. This looks up the MIME type from the content header and instantiates the appropriate
092 * concrete message type.
093 *
094 * @param deliveryTag the AMQ message id
095 * @param redelivered true if redelivered
096 * @param contentHeader the content header that was received
097 * @param bodies a list of ContentBody instances @return the message.
098 * @throws AMQException
099 * @throws JMSException
100 */
101 public AbstractJMSMessage createMessage(long deliveryTag, boolean redelivered, AMQShortString exchange,
102 AMQShortString routingKey, ContentHeaderBody contentHeader, List bodies)
103 throws AMQException, JMSException
104 {
105 BasicContentHeaderProperties properties = (BasicContentHeaderProperties) contentHeader.properties;
106
107 // Get the message content type. This may be null for pure AMQP messages, but will always be set for JMS over
108 // AMQP. When the type is null, it can only be assumed that the message is a byte message.
109 AMQShortString contentTypeShortString = properties.getContentType();
110 contentTypeShortString = (contentTypeShortString == null) ? new AMQShortString(
111 JMSBytesMessage.MIME_TYPE) : contentTypeShortString;
112
113 MessageFactory mf = _mimeShortStringToFactoryMap.get(contentTypeShortString);
114 if (mf == null)
115 {
116 throw new AMQException(null, "Unsupport MIME type of " + properties.getContentTypeAsString(), null);
117 }
118 else
119 {
120 return mf.createMessage(deliveryTag, redelivered, contentHeader, exchange, routingKey, bodies);
121 }
122 }
123
124 public AbstractJMSMessage createMessage(MessageTransfer transfer) throws AMQException, JMSException
125 {
126
127 MessageProperties mprop = transfer.getHeader().get(MessageProperties.class);
128 String messageType = "";
129 if ( mprop == null || mprop.getContentType() == null)
130 {
131 _logger.debug("no message type specified, building a byte message");
132 messageType = JMSBytesMessage.MIME_TYPE;
133 }
134 else
135 {
136 messageType = mprop.getContentType();
137 }
138 MessageFactory mf = _mimeStringToFactoryMap.get(messageType);
139 if (mf == null)
140 {
141 throw new AMQException(null, "Unsupport MIME type of " + messageType, null);
142 }
143 else
144 {
145 boolean redelivered = false;
146 DeliveryProperties deliverProps;
147 if((deliverProps = transfer.getHeader().get(DeliveryProperties.class)) != null)
148 {
149 redelivered = deliverProps.getRedelivered();
150 }
151 return mf.createMessage(transfer.getId(),
152 redelivered,
153 mprop == null? new MessageProperties():mprop,
154 deliverProps == null? new DeliveryProperties():deliverProps,
155 transfer.getBody());
156 }
157 }
158
159
160 public AbstractJMSMessage createMessage(AMQMessageDelegateFactory delegateFactory, String mimeType) throws AMQException, JMSException
161 {
162 if (mimeType == null)
163 {
164 throw new IllegalArgumentException("Mime type must not be null");
165 }
166
167 MessageFactory mf = _mimeStringToFactoryMap.get(mimeType);
168 if (mf == null)
169 {
170 throw new AMQException(null, "Unsupport MIME type of " + mimeType, null);
171 }
172 else
173 {
174 return mf.createMessage(delegateFactory);
175 }
176 }
177 }
|