001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.activemq.console.filter;
018
019 import java.lang.reflect.Method;
020 import java.util.Enumeration;
021 import java.util.HashMap;
022 import java.util.Iterator;
023 import java.util.Map;
024 import java.util.Properties;
025
026 import javax.jms.DeliveryMode;
027 import javax.jms.JMSException;
028 import javax.management.Attribute;
029 import javax.management.AttributeList;
030 import javax.management.ObjectInstance;
031 import javax.management.ObjectName;
032 import javax.management.openmbean.CompositeDataSupport;
033
034 import org.apache.activemq.command.ActiveMQBytesMessage;
035 import org.apache.activemq.command.ActiveMQDestination;
036 import org.apache.activemq.command.ActiveMQMapMessage;
037 import org.apache.activemq.command.ActiveMQMessage;
038 import org.apache.activemq.command.ActiveMQObjectMessage;
039 import org.apache.activemq.command.ActiveMQStreamMessage;
040 import org.apache.activemq.command.ActiveMQTextMessage;
041 import org.apache.activemq.console.util.AmqMessagesUtil;
042
043 public class MapTransformFilter extends ResultTransformFilter {
044 /**
045 * Creates a Map transform filter that is able to transform a variety of
046 * objects to a properties map object
047 *
048 * @param next - the next query filter
049 */
050 public MapTransformFilter(QueryFilter next) {
051 super(next);
052 }
053
054 /**
055 * Transform the given object to a Map object
056 *
057 * @param object - object to transform
058 * @return map object
059 */
060 protected Object transformElement(Object object) throws Exception {
061 // Use reflection to determine how the object should be transformed
062 try {
063 Method method = this.getClass().getDeclaredMethod("transformToMap", new Class[] {
064 object.getClass()
065 });
066 return (Map)method.invoke(this, new Object[] {
067 object
068 });
069 } catch (NoSuchMethodException e) {
070 // CommandContext.print("Unable to transform mbean of type: " + object.getClass().getName() + ". No corresponding transformToMap method found.");
071 return null;
072 }
073 }
074
075 /**
076 * Transform an ObjectInstance mbean to a Map
077 *
078 * @param obj - ObjectInstance format of an mbean
079 * @return map object
080 */
081 protected Map transformToMap(ObjectInstance obj) {
082 return transformToMap(obj.getObjectName());
083 }
084
085 /**
086 * Transform an ObjectName mbean to a Map
087 *
088 * @param objname - ObjectName format of an mbean
089 * @return map object
090 */
091 protected Map transformToMap(ObjectName objname) {
092 Properties props = new Properties();
093
094 // Parse object properties
095 Map objProps = objname.getKeyPropertyList();
096 for (Iterator i = objProps.keySet().iterator(); i.hasNext();) {
097 Object key = i.next();
098 Object val = objProps.get(key);
099 if (val != null) {
100 props.setProperty(key.toString(), val.toString());
101 }
102 }
103
104 return props;
105 }
106
107 /**
108 * Transform an Attribute List format of an mbean to a Map
109 *
110 * @param list - AttributeList format of an mbean
111 * @return map object
112 */
113 protected Map transformToMap(AttributeList list) {
114 Properties props = new Properties();
115 for (Iterator i = list.iterator(); i.hasNext();) {
116 Attribute attrib = (Attribute)i.next();
117
118 // If attribute is an ObjectName
119 if (attrib.getName().equals(MBeansAttributeQueryFilter.KEY_OBJECT_NAME_ATTRIBUTE)) {
120 props.putAll(transformToMap((ObjectName)attrib.getValue()));
121 } else {
122 if (attrib.getValue() != null) {
123 props.setProperty(attrib.getName(), attrib.getValue().toString());
124 }
125 }
126 }
127
128 return props;
129 }
130
131 /**
132 * Transform an ActiveMQTextMessage to a Map
133 *
134 * @param msg - text message to trasnform
135 * @return map object
136 * @throws JMSException
137 */
138 protected Map transformToMap(ActiveMQTextMessage msg) throws JMSException {
139 Properties props = new Properties();
140
141 props.putAll(transformToMap((ActiveMQMessage)msg));
142 if (msg.getText() != null) {
143 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSText", msg.getText());
144 }
145
146 return props;
147 }
148
149 /**
150 * Transform an ActiveMQBytesMessage to a Map
151 *
152 * @param msg - bytes message to transform
153 * @return map object
154 * @throws JMSException
155 */
156 protected Map transformToMap(ActiveMQBytesMessage msg) throws JMSException {
157 Properties props = new Properties();
158
159 props.putAll(transformToMap((ActiveMQMessage)msg));
160
161 long bodyLength = msg.getBodyLength();
162 byte[] msgBody;
163 int i = 0;
164 // Create separate bytes messages
165 for (i = 0; i < (bodyLength / Integer.MAX_VALUE); i++) {
166 msgBody = new byte[Integer.MAX_VALUE];
167 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSBytes:" + (i + 1), new String(msgBody));
168 }
169 msgBody = new byte[(int)(bodyLength % Integer.MAX_VALUE)];
170 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSBytes:" + (i + 1), new String(msgBody));
171
172 return props;
173 }
174
175 /**
176 * Transform an ActiveMQMessage to a Map
177 *
178 * @param msg - object message to transform
179 * @return map object
180 * @throws JMSException
181 */
182 protected Map transformToMap(ActiveMQObjectMessage msg) throws JMSException {
183 Properties props = new Properties();
184
185 props.putAll(transformToMap((ActiveMQMessage)msg));
186 if (msg.getObject() != null) {
187 // Just add the class name and toString value of the object
188 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSObjectClass", msg.getObject().getClass().getName());
189 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSObjectString", msg.getObject().toString());
190 }
191 return props;
192 }
193
194 /**
195 * Transform an ActiveMQMapMessage to a Map
196 *
197 * @param msg - map message to transform
198 * @return map object
199 * @throws JMSException
200 */
201 protected Map transformToMap(ActiveMQMapMessage msg) throws JMSException {
202 Properties props = new Properties();
203
204 props.putAll(transformToMap((ActiveMQMessage)msg));
205
206 // Get map properties
207 Enumeration e = msg.getMapNames();
208 while (e.hasMoreElements()) {
209 String key = (String)e.nextElement();
210 Object val = msg.getObject(key);
211 if (val != null) {
212 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + key, val.toString());
213 }
214 }
215
216 return props;
217 }
218
219 /**
220 * Transform an ActiveMQStreamMessage to a Map
221 *
222 * @param msg - stream message to transform
223 * @return map object
224 * @throws JMSException
225 */
226 protected Map transformToMap(ActiveMQStreamMessage msg) throws JMSException {
227 Properties props = new Properties();
228
229 props.putAll(transformToMap((ActiveMQMessage)msg));
230 // Just set the toString of the message as the body of the stream
231 // message
232 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "JMSStreamMessage", msg.toString());
233
234 return props;
235 }
236
237 /**
238 * Transform an ActiveMQMessage to a Map
239 *
240 * @param msg - message to transform
241 * @return map object
242 * @throws JMSException
243 */
244 protected Map<String, String> transformToMap(ActiveMQMessage msg) throws JMSException {
245 Map<String, String> props = new HashMap<String, String>();
246
247 // Get JMS properties
248 if (msg.getJMSCorrelationID() != null) {
249 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSCorrelationID", msg.getJMSCorrelationID());
250 }
251 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSDeliveryMode", (msg.getJMSDeliveryMode() == DeliveryMode.PERSISTENT) ? "persistent" : "non-persistent");
252 if (msg.getJMSDestination() != null) {
253 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSDestination", ((ActiveMQDestination)msg.getJMSDestination()).getPhysicalName());
254 }
255 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSExpiration", Long.toString(msg.getJMSExpiration()));
256 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSMessageID", msg.getJMSMessageID());
257 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSPriority", Integer.toString(msg.getJMSPriority()));
258 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSRedelivered", Boolean.toString(msg.getJMSRedelivered()));
259 if (msg.getJMSReplyTo() != null) {
260 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSReplyTo", ((ActiveMQDestination)msg.getJMSReplyTo()).getPhysicalName());
261 }
262 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSTimestamp", Long.toString(msg.getJMSTimestamp()));
263 if (msg.getJMSType() != null) {
264 props.put(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSType", msg.getJMSType());
265 }
266
267 // Get custom properties
268 Enumeration e = msg.getPropertyNames();
269 while (e.hasMoreElements()) {
270 String name = (String)e.nextElement();
271 if (msg.getObjectProperty(name) != null) {
272 props.put(AmqMessagesUtil.JMS_MESSAGE_CUSTOM_PREFIX + name, msg.getObjectProperty(name).toString());
273 }
274 }
275
276 return props;
277 }
278
279 /**
280 * Transform an openMBean composite data to a Map
281 *
282 * @param data - composite data to transform
283 * @return map object
284 */
285 protected Map transformToMap(CompositeDataSupport data) {
286 Properties props = new Properties();
287
288 String typeName = data.getCompositeType().getTypeName();
289
290 // Retrieve text message
291 if (typeName.equals(ActiveMQTextMessage.class.getName())) {
292 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "Text", data.get("Text").toString());
293
294 // Retrieve byte preview
295 } else if (typeName.equals(ActiveMQBytesMessage.class.getName())) {
296 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "BodyLength", data.get("BodyLength").toString());
297 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + "BodyPreview", new String((byte[])data.get("BodyPreview")));
298
299 // Expand content map
300 } else if (typeName.equals(ActiveMQMapMessage.class.getName())) {
301 Map contentMap = (Map)data.get("ContentMap");
302 for (Iterator i = contentMap.keySet().iterator(); i.hasNext();) {
303 String key = (String)i.next();
304 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_BODY_PREFIX + key, contentMap.get(key).toString());
305 }
306
307 // Do nothing
308 } else if (typeName.equals(ActiveMQObjectMessage.class.getName()) || typeName.equals(ActiveMQStreamMessage.class.getName()) || typeName.equals(ActiveMQMessage.class.getName())) {
309
310 // Unrecognized composite data. Throw exception.
311 } else {
312 throw new IllegalArgumentException("Unrecognized composite data to transform. composite type: " + typeName);
313 }
314
315 // Process the JMS message header values
316 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSCorrelationID", "" + data.get("JMSCorrelationID"));
317 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSDestination", "" + data.get("JMSDestination"));
318 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSMessageID", "" + data.get("JMSMessageID"));
319 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSReplyTo", "" + data.get("JMSReplyTo"));
320 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSType", "" + data.get("JMSType"));
321 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSDeliveryMode", "" + data.get("JMSDeliveryMode"));
322 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSExpiration", "" + data.get("JMSExpiration"));
323 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSPriority", "" + data.get("JMSPriority"));
324 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSRedelivered", "" + data.get("JMSRedelivered"));
325 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_HEADER_PREFIX + "JMSTimestamp", "" + data.get("JMSTimestamp"));
326
327 // Process the JMS custom message properties
328 props.setProperty(AmqMessagesUtil.JMS_MESSAGE_CUSTOM_PREFIX + "Properties", "" + data.get("Properties"));
329
330 return props;
331 }
332 }