001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements.  See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License.  You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.granite.gravity.selector;
019
020import java.math.BigDecimal;
021
022import javax.jms.JMSException;
023
024/**
025 * Represents a constant expression
026 *
027 * @version $Revision: 1.2 $
028 */
029public class ConstantExpression implements Expression {
030
031    static class BooleanConstantExpression extends ConstantExpression implements BooleanExpression {
032        public BooleanConstantExpression(Object value) {
033            super(value);
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 static ConstantExpression createFromDecimal(String text) {
048
049        // Strip off the 'l' or 'L' if needed.
050        if( text.endsWith("l") || text.endsWith("L") )
051            text = text.substring(0, text.length()-1);
052
053        Number value;
054        try {
055            value = new Long(text);
056        } catch ( NumberFormatException e) {
057            // The number may be too big to fit in a long.
058            value = new BigDecimal(text);
059        }
060
061        long l = value.longValue();
062        if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
063            value = new Integer(value.intValue());
064        }
065        return new ConstantExpression(value);
066    }
067
068    public static ConstantExpression createFromHex(String text) {
069        Number value = new Long(Long.parseLong(text.substring(2), 16));
070        long l = value.longValue();
071        if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
072            value = new Integer(value.intValue());
073        }
074        return new ConstantExpression(value);
075    }
076
077    public static ConstantExpression createFromOctal(String text) {
078        Number value = new Long(Long.parseLong(text, 8));
079        long l = value.longValue();
080        if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE) {
081            value = new Integer(value.intValue());
082        }
083        return new ConstantExpression(value);
084    }
085
086    public static ConstantExpression createFloat(String text) {
087        Number value = new Double(text);
088        return new ConstantExpression(value);
089    }
090
091    public ConstantExpression(Object value) {
092        this.value = value;
093    }
094
095    public Object evaluate(MessageEvaluationContext message) throws JMSException {
096        return value;
097    }
098
099    public Object getValue() {
100        return value;
101    }
102
103    /**
104     * @see java.lang.Object#toString()
105     */
106    @Override
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    @Override
126    public int hashCode() {
127        return toString().hashCode();
128    }
129
130    /**
131     * TODO: more efficient hashCode()
132     *
133     * @see java.lang.Object#equals(java.lang.Object)
134     */
135    @Override
136    public boolean equals(Object o) {
137
138        if (o == null || !this.getClass().equals(o.getClass())) {
139            return false;
140        }
141        return toString().equals(o.toString());
142
143    }
144
145
146    /**
147     * Encodes the value of string so that it looks like it would look like
148     * when it was provided in a selector.
149     *
150     * @param s the string to encode
151     * @return the encoded string
152     */
153    public static String encodeString(String s) {
154        StringBuffer b = new StringBuffer();
155        b.append('\'');
156        for (int i = 0; i < s.length(); i++) {
157            char c = s.charAt(i);
158            if (c == '\'') {
159                b.append(c);
160            }
161            b.append(c);
162        }
163        b.append('\'');
164        return b.toString();
165    }
166
167}