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