001: /*--
002:
003: Copyright (C) 2002 Anthony Eden.
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009:
010: 1. Redistributions of source code must retain the above copyright
011: notice, this list of conditions, and the following disclaimer.
012:
013: 2. Redistributions in binary form must reproduce the above copyright
014: notice, this list of conditions, and the disclaimer that follows
015: these conditions in the documentation and/or other materials
016: provided with the distribution.
017:
018: 3. The names "OBE" and "Open Business Engine" must not be used to
019: endorse or promote products derived from this software without prior
020: written permission. For written permission, please contact
021: me@anthonyeden.com.
022:
023: 4. Products derived from this software may not be called "OBE" or
024: "Open Business Engine", nor may "OBE" or "Open Business Engine"
025: appear in their name, without prior written permission from
026: Anthony Eden (me@anthonyeden.com).
027:
028: In addition, I request (but do not require) that you include in the
029: end-user documentation provided with the redistribution and/or in the
030: software itself an acknowledgement equivalent to the following:
031: "This product includes software developed by
032: Anthony Eden (http://www.anthonyeden.com/)."
033:
034: THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035: WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
036: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
037: DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
038: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
039: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
040: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
041: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
042: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
043: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
044: POSSIBILITY OF SUCH DAMAGE.
045:
046: For more information on OBE, please see <http://obe.sourceforge.net/>.
047:
048: */
049: package org.wfmc.wapi;
050:
051: import java.io.Serializable;
052: import java.util.Date;
053: import java.util.HashMap;
054: import java.util.Map;
055:
056: public class WMFilter implements Serializable {
057: private static final long serialVersionUID = 5124556516649744414L;
058:
059: // WFMC-TC-1013: wmapi2.h claims there are 255 reserved filter types with
060: // ordinals in the range 1..255, however, these constants are not defined
061: // anywhere. So here's an arbitrary stab at assigning two types:
062: public static final int SIMPLE_TYPE = 1;
063: public static final int SQL_TYPE = 2;
064:
065: // WFMC-TC-1013 isn't clear, but it appears that comparisons are represented
066: // by integer codes formed from the operators' 8-bit ASCII character codes.
067: public static final int NO = 0;
068: public static final int LT = '<';
069: public static final int LE = '<' << 8 | '=';
070: public static final int EQ = '=';
071: public static final int NE = '!' << 8 | '=';
072: public static final int GE = '>' << 8 | '=';
073: public static final int GT = '>';
074:
075: // N.B. These are SQL-style operator symbols, not Java.
076: private static final String LT_STR = "<";
077: private static final String LE_STR = "<=";
078: private static final String EQ_STR = "=";
079: private static final String NE_STR = "<>";
080: private static final String GE_STR = ">=";
081: private static final String GT_STR = ">";
082: private static final Map SQL_COMPARISONS = new HashMap();
083:
084: private int filterType;
085: private String attributeName;
086: private int attributeType;
087: private int comparison;
088: private Object filterValue;
089:
090: static {
091: SQL_COMPARISONS.put(new Integer(LT), LT_STR);
092: SQL_COMPARISONS.put(new Integer(LE), LE_STR);
093: SQL_COMPARISONS.put(new Integer(EQ), EQ_STR);
094: SQL_COMPARISONS.put(new Integer(NE), NE_STR);
095: SQL_COMPARISONS.put(new Integer(GE), GE_STR);
096: SQL_COMPARISONS.put(new Integer(GT), GT_STR);
097: }
098:
099: /**
100: * Construct a new filter based on the value of a single attribute. The
101: * attribute must be of type {@link WMAttribute#BOOLEAN_TYPE}.
102: *
103: * @param attributeName The name of the attribute to test.
104: * @param comparison The comparison to use, either {@link #EQ} or
105: * {@link #NE}.
106: * @param attributeValue The boolean value to test.
107: */
108: public WMFilter(String attributeName, int comparison,
109: Boolean attributeValue) {
110:
111: this (SIMPLE_TYPE, attributeName, WMAttribute.BOOLEAN_TYPE,
112: comparison, attributeValue);
113: }
114:
115: /**
116: * Construct a new filter based on the value of a single attribute. The
117: * attribute must be of type {@link WMAttribute#BOOLEAN_TYPE}.
118: *
119: * @param attributeName The name of the attribute to test.
120: * @param comparison The comparison to use, either {@link #EQ} or
121: * {@link #NE}.
122: * @param attributeValue The boolean value to test.
123: */
124: public WMFilter(String attributeName, int comparison,
125: boolean attributeValue) {
126:
127: this (SIMPLE_TYPE, attributeName, WMAttribute.BOOLEAN_TYPE,
128: comparison, attributeValue ? Boolean.TRUE
129: : Boolean.FALSE);
130: }
131:
132: /**
133: * Construct a new filter based on the value of a single attribute. The
134: * attribute must be of type {@link WMAttribute#DATETIME_TYPE}.
135: *
136: * @param attributeName The name of the attribute to test.
137: * @param comparison The comparison to use, one of:
138: * {@link #LT}, {@link #LE}, {@link #EQ}, {@link #NE}, {@link #GE},
139: * {@link #GT}.
140: * @param attributeValue The date value to test.
141: */
142: public WMFilter(String attributeName, int comparison,
143: Date attributeValue) {
144:
145: this (SIMPLE_TYPE, attributeName, WMAttribute.DATETIME_TYPE,
146: comparison, attributeValue);
147: }
148:
149: /**
150: * Construct a new filter based on the value of a single attribute. The
151: * attribute must be of type {@link WMAttribute#FLOAT_TYPE}.
152: *
153: * @param attributeName The name of the attribute to test.
154: * @param comparison The comparison to use, one of:
155: * {@link #LT}, {@link #LE}, {@link #EQ}, {@link #NE}, {@link #GE},
156: * {@link #GT}.
157: * @param attributeValue The floating point value to test.
158: */
159: public WMFilter(String attributeName, int comparison,
160: Double attributeValue) {
161:
162: this (SIMPLE_TYPE, attributeName, WMAttribute.FLOAT_TYPE,
163: comparison, attributeValue);
164: }
165:
166: /**
167: * Construct a new filter based on the value of a single attribute. The
168: * attribute must be of type {@link WMAttribute#FLOAT_TYPE}.
169: *
170: * @param attributeName The name of the attribute to test.
171: * @param comparison The comparison to use, one of:
172: * {@link #LT}, {@link #LE}, {@link #EQ}, {@link #NE}, {@link #GE},
173: * {@link #GT}.
174: * @param attributeValue The floating point value to test.
175: */
176: public WMFilter(String attributeName, int comparison,
177: double attributeValue) {
178:
179: this (SIMPLE_TYPE, attributeName, WMAttribute.FLOAT_TYPE,
180: comparison, new Double(attributeValue));
181: }
182:
183: /**
184: * Construct a new filter based on the value of a single attribute. The
185: * attribute must be of type {@link WMAttribute#INTEGER_TYPE}.
186: *
187: * @param attributeName The name of the attribute to test.
188: * @param comparison The comparison to use, one of:
189: * {@link #LT}, {@link #LE}, {@link #EQ}, {@link #NE}, {@link #GE},
190: * {@link #GT}.
191: * @param attributeValue The integer value to test.
192: */
193: public WMFilter(String attributeName, int comparison,
194: Integer attributeValue) {
195:
196: this (SIMPLE_TYPE, attributeName, WMAttribute.INTEGER_TYPE,
197: comparison, attributeValue);
198: }
199:
200: /**
201: * Construct a new filter based on the value of a single attribute. The
202: * attribute must be of type {@link WMAttribute#INTEGER_TYPE}.
203: *
204: * @param attributeName The name of the attribute to test.
205: * @param comparison The comparison to use, one of:
206: * {@link #LT}, {@link #LE}, {@link #EQ}, {@link #NE}, {@link #GE},
207: * {@link #GT}.
208: * @param attributeValue The integer value to test.
209: */
210: public WMFilter(String attributeName, int comparison,
211: int attributeValue) {
212:
213: this (SIMPLE_TYPE, attributeName, WMAttribute.INTEGER_TYPE,
214: comparison, new Integer(attributeValue));
215: }
216:
217: /**
218: * Construct a new filter based on the value of a single attribute. The
219: * attribute must be of type {@link WMAttribute#STRING_TYPE} or
220: * {@link WMAttribute#PERFORMER_TYPE}.
221: *
222: * @param attributeName The name of the attribute to test.
223: * @param comparison The comparison to use, one of:
224: * {@link #LT}, {@link #LE}, {@link #EQ}, {@link #NE}, {@link #GE},
225: * {@link #GT}.
226: * @param attributeValue The string value to test.
227: */
228: public WMFilter(String attributeName, int comparison,
229: String attributeValue) {
230:
231: this (SIMPLE_TYPE, attributeName, WMAttribute.STRING_TYPE,
232: comparison, attributeValue);
233: }
234:
235: /**
236: * Construct a new filter based on an SQL query predicate. The predicate
237: * must only reference fields defined for the entity type to be queried.
238: *
239: * @param sqlString A standard SQL-92 WHERE clause predicate. Joins are
240: * not supported.
241: */
242: public WMFilter(String sqlString) {
243: this (SQL_TYPE, null, WMAttribute.STRING_TYPE, NO, sqlString);
244: }
245:
246: private WMFilter(int filterType, String attributeName,
247: int attributeType, int comparison, Object filterValue) {
248:
249: if (filterType != SIMPLE_TYPE && filterType != SQL_TYPE)
250: throw new IllegalArgumentException("filterType: "
251: + filterType);
252: if (filterType == SIMPLE_TYPE && comparison != LT
253: && comparison != LE && comparison != EQ
254: && comparison != NE && comparison != GE
255: && comparison != GT) {
256:
257: throw new IllegalArgumentException("comparison: "
258: + String.valueOf(comparison));
259: }
260: if (filterType == SIMPLE_TYPE) {
261: if (attributeName != null)
262: attributeName = attributeName.trim();
263: if (attributeName == null || attributeName.length() == 0) {
264: throw new IllegalArgumentException("attributeName: "
265: + attributeName);
266: }
267: }
268: this .filterType = filterType;
269: this .attributeName = attributeName;
270: this .attributeType = attributeType;
271: this .comparison = comparison;
272: this .filterValue = filterValue;
273: }
274:
275: public String getAttributeName() {
276: return attributeName;
277: }
278:
279: public int getAttributeType() {
280: return attributeType;
281: }
282:
283: public int getComparison() {
284: return comparison;
285: }
286:
287: public String getFilterString() {
288: return filterValue == null ? null : filterValue.toString();
289: }
290:
291: public int getFilterType() {
292: return filterType;
293: }
294:
295: public Object getFilterValue() {
296: return filterValue;
297: }
298:
299: public String getSQLComparison() {
300: return (String) SQL_COMPARISONS.get(new Integer(comparison));
301: }
302:
303: public String toString() {
304: return "WMFilter[filterType=" + filterType
305: + ", attributeName='" + attributeName + '\''
306: + ", comparison=" + comparison + ", filterValue='"
307: + filterValue + '\'' + ']';
308: }
309: }
|