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