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.filter;
018    
019    import java.math.BigDecimal;
020    
021    import javax.jms.JMSException;
022    
023    /**
024     * Represents a constant expression
025     * 
026     * 
027     */
028    public class ConstantExpression implements Expression {
029    
030        static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression {
031            public BooleanConstantExpression(Object value) {
032                super(value);
033            }
034    
035            public boolean matches(MessageEvaluationContext message) throws JMSException {
036                Object object = evaluate(message);
037                return object != null && object == Boolean.TRUE;
038            }
039        }
040    
041        public static final BooleanConstantExpression NULL = new BooleanConstantExpression(null);
042        public static final BooleanConstantExpression TRUE = new BooleanConstantExpression(Boolean.TRUE);
043        public static final BooleanConstantExpression FALSE = new BooleanConstantExpression(Boolean.FALSE);
044    
045        private Object value;
046    
047        public ConstantExpression(Object value) {
048            this.value = value;
049        }
050    
051        public static ConstantExpression createFromDecimal(String text) {
052    
053            // Strip off the 'l' or 'L' if needed.
054            if (text.endsWith("l") || text.endsWith("L")) {
055                text = text.substring(0, text.length() - 1);
056            }
057    
058            Number value;
059            try {
060                value = new Long(text);
061            } catch (NumberFormatException e) {
062                // The number may be too big to fit in a long.
063                value = new BigDecimal(text);
064            }
065    
066            long l = value.longValue();
067            if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
068                value = Integer.valueOf(value.intValue());
069            }
070            return new ConstantExpression(value);
071        }
072    
073        public static ConstantExpression createFromHex(String text) {
074            Number value = Long.valueOf(Long.parseLong(text.substring(2), 16));
075            long l = value.longValue();
076            if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
077                value = Integer.valueOf(value.intValue());
078            }
079            return new ConstantExpression(value);
080        }
081    
082        public static ConstantExpression createFromOctal(String text) {
083            Number value = Long.valueOf(Long.parseLong(text, 8));
084            long l = value.longValue();
085            if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
086                value = Integer.valueOf(value.intValue());
087            }
088            return new ConstantExpression(value);
089        }
090    
091        public static ConstantExpression createFloat(String text) {
092            Number value = new Double(text);
093            return new ConstantExpression(value);
094        }
095    
096        public Object evaluate(MessageEvaluationContext message) throws JMSException {
097            return value;
098        }
099    
100        public Object getValue() {
101            return value;
102        }
103    
104        /**
105         * @see java.lang.Object#toString()
106         */
107        public String toString() {
108            if (value == null) {
109                return "NULL";
110            }
111            if (value instanceof Boolean) {
112                return ((Boolean)value).booleanValue() ? "TRUE" : "FALSE";
113            }
114            if (value instanceof String) {
115                return encodeString((String)value);
116            }
117            return value.toString();
118        }
119    
120        /**
121         * TODO: more efficient hashCode()
122         * 
123         * @see java.lang.Object#hashCode()
124         */
125        public int hashCode() {
126            return toString().hashCode();
127        }
128    
129        /**
130         * TODO: more efficient hashCode()
131         * 
132         * @see java.lang.Object#equals(java.lang.Object)
133         */
134        public boolean equals(Object o) {
135    
136            if (o == null || !this.getClass().equals(o.getClass())) {
137                return false;
138            }
139            return toString().equals(o.toString());
140    
141        }
142    
143        /**
144         * Encodes the value of string so that it looks like it would look like when
145         * it was provided in a selector.
146         * 
147         * @param string
148         * @return
149         */
150        public static String encodeString(String s) {
151            StringBuffer b = new StringBuffer();
152            b.append('\'');
153            for (int i = 0; i < s.length(); i++) {
154                char c = s.charAt(i);
155                if (c == '\'') {
156                    b.append(c);
157                }
158                b.append(c);
159            }
160            b.append('\'');
161            return b.toString();
162        }
163    
164    }