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 */
017package org.apache.activemq.filter;
018
019import java.math.BigDecimal;
020
021import javax.jms.JMSException;
022
023/**
024 * Represents a constant expression
025 * 
026 * 
027 */
028public 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}