001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.filter;
017:
018: import java.awt.Color;
019: import java.math.BigDecimal;
020: import java.util.Date;
021: import com.vividsolutions.jts.geom.Geometry;
022: import org.opengis.filter.expression.Add;
023: import org.opengis.filter.expression.Divide;
024: import org.opengis.filter.expression.ExpressionVisitor;
025: import org.opengis.filter.expression.Function;
026: import org.opengis.filter.expression.Literal;
027: import org.opengis.filter.expression.Multiply;
028: import org.opengis.filter.expression.NilExpression;
029: import org.opengis.filter.expression.PropertyName;
030: import org.opengis.filter.expression.Subtract;
031: import org.geotools.feature.Feature;
032:
033: /**
034: * The Expression class is not immutable!
035: * <p>
036: * However we do have a need for immutable literal expressions when
037: * defining our API for SLD, and any other standards based on
038: * Expression.
039: * </p>
040: *
041: * @author Jody Garnett, Refractions Research
042: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/api/src/main/java/org/geotools/filter/ConstantExpression.java $
043: */
044: public class ConstantExpression implements LiteralExpression, Cloneable {
045: public static final ConstantExpression NULL = constant(null);
046: public static final ConstantExpression BLACK = color(Color.BLACK);
047: public static final ConstantExpression ZERO = constant(0);
048: public static final ConstantExpression ONE = constant(1);
049: public static final ConstantExpression TWO = constant(2);
050: public static final ConstantExpression UNNAMED = constant("");
051: final short type;
052: Object value;
053:
054: protected ConstantExpression(Object value) {
055: this (type(value), value);
056: }
057:
058: protected ConstantExpression(short type, Object value) {
059: this .type = type;
060: this .value = value;
061: }
062:
063: /**
064: * @deprecated use {@link #setValue(Object)}
065: */
066: public final void setLiteral(Object literal)
067: throws IllegalFilterException {
068: throw new UnsupportedOperationException(
069: "Default value is immutable");
070: }
071:
072: /**
073: * @deprecated use {@link #evaluate(Feature)}
074: */
075: public final Object getValue(Feature feature) {
076: return evaluate(feature);
077: }
078:
079: public Object evaluate(Feature feature) {
080: return getValue();
081: }
082:
083: public Object evaluate(Object object) {
084: return getValue();
085: }
086:
087: public Object evaluate(Object object, Class context) {
088: if ((value == null) || value.getClass().equals(context)) {
089: return value;
090: } else {
091: return null;
092: }
093: }
094:
095: public Object getValue() {
096: return value;
097: }
098:
099: public void setValue(Object constant) {
100: throw new UnsupportedOperationException(
101: "Default value is immutable");
102: }
103:
104: public short getType() {
105: return type;
106: }
107:
108: /**
109: * @deprecated use {@link #getValue()}
110: */
111: public final Object getLiteral() {
112: return getValue();
113: }
114:
115: /**
116: * @deprecated use {@link #accept(ExpressionVisitor, Object)}.
117: */
118: public void accept(final FilterVisitor visitor) {
119: accept(new ExpressionVisitor() {
120: public Object visit(Add expression, Object extraData) {
121: return null;
122: }
123:
124: public Object visit(Divide expression, Object extraData) {
125: return null;
126: }
127:
128: public Object visit(Function expression, Object extraData) {
129: return null;
130: }
131:
132: public Object visit(Literal expression, Object extraData) {
133: visitor.visit(ConstantExpression.this );
134:
135: return null;
136: }
137:
138: public Object visit(Multiply expression, Object extraData) {
139: return null;
140: }
141:
142: public Object visit(PropertyName expression,
143: Object extraData) {
144: return null;
145: }
146:
147: public Object visit(Subtract expression, Object extraData) {
148: return null;
149: }
150:
151: public Object visit(NilExpression arg0, Object arg1) {
152: return null;
153: }
154: }, null);
155: }
156:
157: public Object accept(ExpressionVisitor visitor, Object extraData) {
158: return visitor.visit(this , extraData);
159: }
160:
161: protected Object clone() throws CloneNotSupportedException {
162: return new ConstantExpression(value);
163: }
164:
165: public boolean equals(Object obj) {
166: if (!(obj instanceof LiteralExpression)) {
167: return false;
168: }
169:
170: LiteralExpression other = (LiteralExpression) obj;
171: Object otherLiteral = other.getValue();
172:
173: if (value == null) {
174: return otherLiteral == null;
175: }
176:
177: if (value.getClass().isAssignableFrom(otherLiteral.getClass())) {
178: return value.equals(other.getValue());
179: }
180:
181: if (value instanceof Number) {
182: if (otherLiteral instanceof Number) {
183: Number myNumber = (Number) value;
184: Number otherNumber = (Number) otherLiteral;
185:
186: return myNumber.doubleValue() == otherNumber
187: .doubleValue();
188: }
189: }
190:
191: // Okay we are into String Compare land!
192: String myString = value.toString();
193: String otherString = otherLiteral.toString();
194:
195: return myString.equals(otherString);
196: }
197:
198: public int hashCode() {
199: if (value instanceof Geometry || value instanceof Date) {
200: // forms of complex content ...
201: return value.hashCode();
202: }
203:
204: return (value == null) ? 0 : value.toString().hashCode();
205: }
206:
207: public String toString() {
208: if (value instanceof Color) {
209: Color color = (Color) value;
210: String redCode = Integer.toHexString(color.getRed());
211: String greenCode = Integer.toHexString(color.getGreen());
212: String blueCode = Integer.toHexString(color.getBlue());
213:
214: if (redCode.length() == 1) {
215: redCode = "0" + redCode;
216: }
217:
218: if (greenCode.length() == 1) {
219: greenCode = "0" + greenCode;
220: }
221:
222: if (blueCode.length() == 1) {
223: blueCode = "0" + blueCode;
224: }
225: }
226:
227: return (value == null) ? "NULL" : value.toString();
228: }
229:
230: /** Encode provided color as a String */
231: public static ConstantExpression color(Color color) {
232: if (color == null) {
233: return NULL;
234: }
235:
236: String redCode = Integer.toHexString(color.getRed());
237: String greenCode = Integer.toHexString(color.getGreen());
238: String blueCode = Integer.toHexString(color.getBlue());
239:
240: if (redCode.length() == 1) {
241: redCode = "0" + redCode;
242: }
243:
244: if (greenCode.length() == 1) {
245: greenCode = "0" + greenCode;
246: }
247:
248: if (blueCode.length() == 1) {
249: blueCode = "0" + blueCode;
250: }
251:
252: String colorCode = "#" + redCode + greenCode + blueCode;
253:
254: return new ConstantExpression(colorCode);
255: }
256:
257: public static ConstantExpression constant(double number) {
258: return new ConstantExpression(new Double(number));
259: }
260:
261: public static ConstantExpression constant(int number) {
262: return new ConstantExpression(new Integer(number));
263: }
264:
265: public static ConstantExpression constant(Object value) {
266: return new ConstantExpression(value);
267: }
268:
269: static short type(Object value) {
270: if (value instanceof Number) {
271: if (value instanceof Double) {
272: return Expression.LITERAL_DOUBLE;
273: } else if (value instanceof BigDecimal) {
274: return Expression.LITERAL_DOUBLE;
275: } else {
276: return Expression.LITERAL_INTEGER;
277: }
278: } else if (value instanceof Geometry) {
279: return Expression.LITERAL_GEOMETRY;
280: }
281:
282: return Expression.LITERAL_STRING;
283: }
284: }
|