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    
018    package org.apache.activemq.filter;
019    
020    import java.io.IOException;
021    import java.util.Arrays;
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import javax.jms.JMSException;
026    
027    import org.apache.activemq.command.ActiveMQDestination;
028    import org.apache.activemq.command.Message;
029    import org.apache.activemq.command.TransactionId;
030    import org.apache.activemq.util.JMSExceptionSupport;
031    
032    /**
033     * Represents a property expression
034     */
035    public class PropertyExpression implements Expression {
036    
037        private static final Map<String, SubExpression> JMS_PROPERTY_EXPRESSIONS = new HashMap<String, SubExpression>();
038    
039        interface SubExpression {
040            Object evaluate(Message message);
041        }
042    
043        static {
044            JMS_PROPERTY_EXPRESSIONS.put("JMSDestination", new SubExpression() {
045    
046                @Override
047                public Object evaluate(Message message) {
048                    ActiveMQDestination dest = message.getOriginalDestination();
049                    if (dest == null) {
050                        dest = message.getDestination();
051                    }
052                    if (dest == null) {
053                        return null;
054                    }
055                    return dest.toString();
056                }
057            });
058            JMS_PROPERTY_EXPRESSIONS.put("JMSReplyTo", new SubExpression() {
059    
060                @Override
061                public Object evaluate(Message message) {
062                    if (message.getReplyTo() == null) {
063                        return null;
064                    }
065                    return message.getReplyTo().toString();
066                }
067            });
068            JMS_PROPERTY_EXPRESSIONS.put("JMSType", new SubExpression() {
069    
070                @Override
071                public Object evaluate(Message message) {
072                    return message.getType();
073                }
074            });
075            JMS_PROPERTY_EXPRESSIONS.put("JMSDeliveryMode", new SubExpression() {
076    
077                @Override
078                public Object evaluate(Message message) {
079                    return message.isPersistent() ? "PERSISTENT" : "NON_PERSISTENT";
080                }
081            });
082            JMS_PROPERTY_EXPRESSIONS.put("JMSPriority", new SubExpression() {
083    
084                @Override
085                public Object evaluate(Message message) {
086                    return Integer.valueOf(message.getPriority());
087                }
088            });
089            JMS_PROPERTY_EXPRESSIONS.put("JMSMessageID", new SubExpression() {
090    
091                @Override
092                public Object evaluate(Message message) {
093                    if (message.getMessageId() == null) {
094                        return null;
095                    }
096                    return message.getMessageId().toString();
097                }
098            });
099            JMS_PROPERTY_EXPRESSIONS.put("JMSTimestamp", new SubExpression() {
100    
101                @Override
102                public Object evaluate(Message message) {
103                    return Long.valueOf(message.getTimestamp());
104                }
105            });
106            JMS_PROPERTY_EXPRESSIONS.put("JMSCorrelationID", new SubExpression() {
107    
108                @Override
109                public Object evaluate(Message message) {
110                    return message.getCorrelationId();
111                }
112            });
113            JMS_PROPERTY_EXPRESSIONS.put("JMSExpiration", new SubExpression() {
114    
115                @Override
116                public Object evaluate(Message message) {
117                    return Long.valueOf(message.getExpiration());
118                }
119            });
120            JMS_PROPERTY_EXPRESSIONS.put("JMSRedelivered", new SubExpression() {
121    
122                @Override
123                public Object evaluate(Message message) {
124                    return Boolean.valueOf(message.isRedelivered());
125                }
126            });
127            JMS_PROPERTY_EXPRESSIONS.put("JMSXDeliveryCount", new SubExpression() {
128    
129                @Override
130                public Object evaluate(Message message) {
131                    return Integer.valueOf(message.getRedeliveryCounter() + 1);
132                }
133            });
134            JMS_PROPERTY_EXPRESSIONS.put("JMSXGroupID", new SubExpression() {
135    
136                @Override
137                public Object evaluate(Message message) {
138                    return message.getGroupID();
139                }
140            });
141            JMS_PROPERTY_EXPRESSIONS.put("JMSXUserID", new SubExpression() {
142    
143                @Override
144                public Object evaluate(Message message) {
145                    Object userId = message.getUserID();
146                    if (userId == null) {
147                        try {
148                            userId = message.getProperty("JMSXUserID");
149                        } catch (IOException e) {
150                        }
151                    }
152    
153                    return userId;
154                }
155            });
156            JMS_PROPERTY_EXPRESSIONS.put("JMSXGroupSeq", new SubExpression() {
157    
158                @Override
159                public Object evaluate(Message message) {
160                    return new Integer(message.getGroupSequence());
161                }
162            });
163            JMS_PROPERTY_EXPRESSIONS.put("JMSXProducerTXID", new SubExpression() {
164    
165                @Override
166                public Object evaluate(Message message) {
167                    TransactionId txId = message.getOriginalTransactionId();
168                    if (txId == null) {
169                        txId = message.getTransactionId();
170                    }
171                    if (txId == null) {
172                        return null;
173                    }
174                    return txId.toString();
175                }
176            });
177            JMS_PROPERTY_EXPRESSIONS.put("JMSActiveMQBrokerInTime", new SubExpression() {
178    
179                @Override
180                public Object evaluate(Message message) {
181                    return Long.valueOf(message.getBrokerInTime());
182                }
183            });
184            JMS_PROPERTY_EXPRESSIONS.put("JMSActiveMQBrokerOutTime", new SubExpression() {
185    
186                @Override
187                public Object evaluate(Message message) {
188                    return Long.valueOf(message.getBrokerOutTime());
189                }
190            });
191            JMS_PROPERTY_EXPRESSIONS.put("JMSActiveMQBrokerPath", new SubExpression() {
192    
193                @Override
194                public Object evaluate(Message message) {
195                    return Arrays.toString(message.getBrokerPath());
196                }
197            });
198            JMS_PROPERTY_EXPRESSIONS.put("JMSXGroupFirstForConsumer", new SubExpression() {
199    
200                @Override
201                public Object evaluate(Message message) {
202                    return Boolean.valueOf(message.isJMSXGroupFirstForConsumer());
203                }
204            });
205        }
206    
207        private final String name;
208        private final SubExpression jmsPropertyExpression;
209    
210        public PropertyExpression(String name) {
211            this.name = name;
212            jmsPropertyExpression = JMS_PROPERTY_EXPRESSIONS.get(name);
213        }
214    
215        @Override
216        public Object evaluate(MessageEvaluationContext message) throws JMSException {
217            try {
218                if (message.isDropped()) {
219                    return null;
220                }
221    
222                if (jmsPropertyExpression != null) {
223                    return jmsPropertyExpression.evaluate(message.getMessage());
224                }
225                try {
226                    return message.getMessage().getProperty(name);
227                } catch (IOException ioe) {
228                    throw JMSExceptionSupport.create("Could not get property: " + name + " reason: " + ioe.getMessage(), ioe);
229                }
230            } catch (IOException e) {
231                throw JMSExceptionSupport.create(e);
232            }
233    
234        }
235    
236        public Object evaluate(Message message) throws JMSException {
237            if (jmsPropertyExpression != null) {
238                return jmsPropertyExpression.evaluate(message);
239            }
240            try {
241                return message.getProperty(name);
242            } catch (IOException ioe) {
243                throw JMSExceptionSupport.create(ioe);
244            }
245        }
246    
247        public String getName() {
248            return name;
249        }
250    
251        /**
252         * @see java.lang.Object#toString()
253         */
254        @Override
255        public String toString() {
256            return name;
257        }
258    
259        /**
260         * @see java.lang.Object#hashCode()
261         */
262        @Override
263        public int hashCode() {
264            return name.hashCode();
265        }
266    
267        /**
268         * @see java.lang.Object#equals(java.lang.Object)
269         */
270        @Override
271        public boolean equals(Object o) {
272    
273            if (o == null || !this.getClass().equals(o.getClass())) {
274                return false;
275            }
276            return name.equals(((PropertyExpression) o).name);
277        }
278    }