001: package org.drools.base.evaluators;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * 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: */
018:
019: import org.drools.base.BaseEvaluator;
020: import org.drools.base.ValueType;
021: import org.drools.common.InternalWorkingMemory;
022: import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
023: import org.drools.rule.VariableRestriction.VariableContextEntry;
024: import org.drools.spi.Evaluator;
025: import org.drools.spi.Extractor;
026: import org.drools.spi.FieldValue;
027:
028: /**
029: * For handling simple (non collection) array types.
030: * @author Michael Neale
031: */
032: public class ArrayFactory implements EvaluatorFactory {
033:
034: private static final long serialVersionUID = 400L;
035: private static EvaluatorFactory INSTANCE = new ArrayFactory();
036:
037: private ArrayFactory() {
038:
039: }
040:
041: public static EvaluatorFactory getInstance() {
042: if (ArrayFactory.INSTANCE == null) {
043: ArrayFactory.INSTANCE = new ArrayFactory();
044: }
045: return ArrayFactory.INSTANCE;
046: }
047:
048: public Evaluator getEvaluator(final Operator operator) {
049: if (operator == Operator.EQUAL) {
050: return ArrayEqualEvaluator.INSTANCE;
051: } else if (operator == Operator.NOT_EQUAL) {
052: return ArrayNotEqualEvaluator.INSTANCE;
053: } else if (operator == Operator.CONTAINS) {
054: return ArrayContainsEvaluator.INSTANCE;
055: } else if (operator == Operator.EXCLUDES) {
056: return ArrayExcludesEvaluator.INSTANCE;
057: } else if (operator == Operator.NOT_CONTAINS) {
058: return ArrayExcludesEvaluator.INSTANCE; // 'not contains' and 'excludes' are synonyms
059: } else if (operator == Operator.MEMBEROF) {
060: return ArrayMemberOfEvaluator.INSTANCE;
061: } else if (operator == Operator.NOTMEMBEROF) {
062: return ArrayNotMemberOfEvaluator.INSTANCE;
063: } else {
064: throw new RuntimeException("Operator '" + operator
065: + "' does not exist for ArrayEvaluator");
066: }
067: }
068:
069: static class ArrayEqualEvaluator extends BaseEvaluator {
070: /**
071: *
072: */
073: private static final long serialVersionUID = 400L;
074: public final static Evaluator INSTANCE = new ArrayEqualEvaluator();
075:
076: private ArrayEqualEvaluator() {
077: super (ValueType.ARRAY_TYPE, Operator.EQUAL);
078: }
079:
080: public boolean evaluate(InternalWorkingMemory workingMemory,
081: final Extractor extractor, final Object object1,
082: final FieldValue object2) {
083: final Object value1 = extractor.getValue(workingMemory,
084: object1);
085: final Object value2 = object2.getValue();
086: if (value1 == null) {
087: return value2 == null;
088: }
089: return value1.equals(value2);
090: }
091:
092: public boolean evaluateCachedRight(
093: InternalWorkingMemory workingMemory,
094: final VariableContextEntry context, final Object left) {
095: final Object value = context.declaration.getExtractor()
096: .getValue(workingMemory, left);
097: if (value == null) {
098: return ((ObjectVariableContextEntry) context).right == null;
099: }
100: return value
101: .equals(((ObjectVariableContextEntry) context).right);
102: }
103:
104: public boolean evaluateCachedLeft(
105: InternalWorkingMemory workingMemory,
106: final VariableContextEntry context, final Object right) {
107: final Object value = context.extractor.getValue(
108: workingMemory, right);
109: if (((ObjectVariableContextEntry) context).left == null) {
110: return value == null;
111: }
112: return ((ObjectVariableContextEntry) context).left
113: .equals(value);
114: }
115:
116: public boolean evaluate(InternalWorkingMemory workingMemory,
117: final Extractor extractor1, final Object object1,
118: final Extractor extractor2, final Object object2) {
119: final Object value1 = extractor1.getValue(workingMemory,
120: object1);
121: final Object value2 = extractor2.getValue(workingMemory,
122: object2);
123: if (value1 == null) {
124: return value2 == null;
125: }
126: return value1.equals(value2);
127: }
128:
129: public String toString() {
130: return "Array ==";
131: }
132:
133: }
134:
135: static class ArrayNotEqualEvaluator extends BaseEvaluator {
136: /**
137: *
138: */
139: private static final long serialVersionUID = 400L;
140: public final static Evaluator INSTANCE = new ArrayNotEqualEvaluator();
141:
142: private ArrayNotEqualEvaluator() {
143: super (ValueType.ARRAY_TYPE, Operator.NOT_EQUAL);
144: }
145:
146: public boolean evaluate(InternalWorkingMemory workingMemory,
147: final Extractor extractor, final Object object1,
148: final FieldValue object2) {
149: final Object value1 = extractor.getValue(workingMemory,
150: object1);
151: final Object value2 = object2.getValue();
152: if (value1 == null) {
153: return value2 != null;
154: }
155: return !value1.equals(value2);
156: }
157:
158: public boolean evaluateCachedRight(
159: InternalWorkingMemory workingMemory,
160: final VariableContextEntry context, final Object left) {
161: final Object value = context.declaration.getExtractor()
162: .getValue(workingMemory, left);
163: if (value == null) {
164: return ((ObjectVariableContextEntry) context).right != null;
165: }
166: return !value
167: .equals(((ObjectVariableContextEntry) context).right);
168: }
169:
170: public boolean evaluateCachedLeft(
171: InternalWorkingMemory workingMemory,
172: final VariableContextEntry context, final Object right) {
173: final Object value = context.extractor.getValue(
174: workingMemory, right);
175: if (((ObjectVariableContextEntry) context).left == null) {
176: return value != null;
177: }
178: return !((ObjectVariableContextEntry) context).left
179: .equals(value);
180: }
181:
182: public boolean evaluate(InternalWorkingMemory workingMemory,
183: final Extractor extractor1, final Object object1,
184: final Extractor extractor2, final Object object2) {
185: final Object value1 = extractor1.getValue(workingMemory,
186: object1);
187: final Object value2 = extractor2.getValue(workingMemory,
188: object2);
189: if (value1 == null) {
190: return value2 != null;
191: }
192: return !value1.equals(value2);
193: }
194:
195: public String toString() {
196: return "Array !=";
197: }
198: }
199:
200: static class ArrayContainsEvaluator extends BaseEvaluator {
201: /**
202: *
203: */
204: private static final long serialVersionUID = 400L;
205: public final static Evaluator INSTANCE = new ArrayContainsEvaluator();
206:
207: private ArrayContainsEvaluator() {
208: super (ValueType.ARRAY_TYPE, Operator.CONTAINS);
209: }
210:
211: public boolean evaluate(InternalWorkingMemory workingMemory,
212: final Extractor extractor, final Object object1,
213: final FieldValue object2) {
214: final Object value = object2.getValue();
215: final Object[] array = (Object[]) extractor.getValue(
216: workingMemory, object1);
217: if (array == null)
218: return false;
219: return ArrayUtils.search(array, value) >= 0;
220: }
221:
222: public boolean evaluateCachedRight(
223: InternalWorkingMemory workingMemory,
224: final VariableContextEntry context, final Object left) {
225: final Object value = context.declaration.getExtractor()
226: .getValue(workingMemory, left);
227: final Object[] array = (Object[]) ((ObjectVariableContextEntry) context).right;
228: if (array == null)
229: return false;
230: return ArrayUtils.search(array, value) >= 0;
231: }
232:
233: public boolean evaluateCachedLeft(
234: InternalWorkingMemory workingMemory,
235: final VariableContextEntry context, final Object right) {
236: final Object value = ((ObjectVariableContextEntry) context).left;
237: final Object[] array = (Object[]) context.extractor
238: .getValue(workingMemory, right);
239: if (array == null)
240: return false;
241: return ArrayUtils.search(array, value) >= 0;
242: }
243:
244: public boolean evaluate(InternalWorkingMemory workingMemory,
245: final Extractor extractor1, final Object object1,
246: final Extractor extractor2, final Object object2) {
247: final Object value = extractor2.getValue(workingMemory,
248: object2);
249: final Object[] array = (Object[]) extractor1.getValue(
250: workingMemory, object1);
251:
252: if (array == null)
253: return false;
254: return ArrayUtils.search(array, value) >= 0;
255: }
256:
257: public String toString() {
258: return "Array contains";
259: }
260: }
261:
262: static class ArrayExcludesEvaluator extends BaseEvaluator {
263: /**
264: *
265: */
266: private static final long serialVersionUID = 400L;
267: public final static Evaluator INSTANCE = new ArrayExcludesEvaluator();
268:
269: private ArrayExcludesEvaluator() {
270: super (ValueType.ARRAY_TYPE, Operator.EXCLUDES);
271: }
272:
273: public boolean evaluate(InternalWorkingMemory workingMemory,
274: final Extractor extractor, final Object object1,
275: final FieldValue object2) {
276: final Object value = object2.getValue();
277: final Object[] array = (Object[]) extractor.getValue(
278: workingMemory, object1);
279: if (array == null)
280: return false;
281: return ArrayUtils.search(array, value) < 0;
282: }
283:
284: public boolean evaluateCachedRight(
285: InternalWorkingMemory workingMemory,
286: final VariableContextEntry context, final Object left) {
287: final Object value = context.declaration.getExtractor()
288: .getValue(workingMemory, left);
289: final Object[] array = (Object[]) ((ObjectVariableContextEntry) context).right;
290: if (array == null)
291: return false;
292: return ArrayUtils.search(array, value) < 0;
293: }
294:
295: public boolean evaluateCachedLeft(
296: InternalWorkingMemory workingMemory,
297: final VariableContextEntry context, final Object right) {
298: final Object value = ((ObjectVariableContextEntry) context).left;
299: final Object[] array = (Object[]) context.extractor
300: .getValue(workingMemory, right);
301: if (array == null)
302: return false;
303: return ArrayUtils.search(array, value) < 0;
304: }
305:
306: public boolean evaluate(InternalWorkingMemory workingMemory,
307: final Extractor extractor1, final Object object1,
308: final Extractor extractor2, final Object object2) {
309: final Object value = extractor2.getValue(workingMemory,
310: object2);
311: final Object[] array = (Object[]) extractor1.getValue(
312: workingMemory, object1);
313:
314: if (array == null)
315: return false;
316: return ArrayUtils.search(array, value) < 0;
317: }
318:
319: public String toString() {
320: return "Array excludes";
321: }
322: }
323:
324: static class ArrayMemberOfEvaluator extends BaseEvaluator {
325: /**
326: *
327: */
328: private static final long serialVersionUID = 400L;
329: public final static Evaluator INSTANCE = new ArrayMemberOfEvaluator();
330:
331: private ArrayMemberOfEvaluator() {
332: super (ValueType.ARRAY_TYPE, Operator.MEMBEROF);
333: }
334:
335: public boolean evaluate(InternalWorkingMemory workingMemory,
336: final Extractor extractor, final Object object1,
337: final FieldValue object2) {
338: final Object[] array = (Object[]) object2.getValue();
339: final Object value = extractor.getValue(workingMemory,
340: object1);
341: if (array == null)
342: return false;
343: return ArrayUtils.search(array, value) >= 0;
344: }
345:
346: public boolean evaluateCachedRight(
347: InternalWorkingMemory workingMemory,
348: final VariableContextEntry context, final Object left) {
349: final Object[] array = (Object[]) context.declaration
350: .getExtractor().getValue(workingMemory, left);
351: final Object value = ((ObjectVariableContextEntry) context).right;
352: if (array == null)
353: return false;
354: return ArrayUtils.search(array, value) >= 0;
355: }
356:
357: public boolean evaluateCachedLeft(
358: InternalWorkingMemory workingMemory,
359: final VariableContextEntry context, final Object right) {
360: final Object[] array = (Object[]) ((ObjectVariableContextEntry) context).left;
361: final Object value = context.extractor.getValue(
362: workingMemory, right);
363: if (array == null)
364: return false;
365: return ArrayUtils.search(array, value) >= 0;
366: }
367:
368: public boolean evaluate(InternalWorkingMemory workingMemory,
369: final Extractor extractor1, final Object object1,
370: final Extractor extractor2, final Object object2) {
371: final Object[] array = (Object[]) extractor2.getValue(
372: workingMemory, object2);
373: final Object value = extractor1.getValue(workingMemory,
374: object1);
375:
376: if (array == null)
377: return false;
378: return ArrayUtils.search(array, value) >= 0;
379: }
380:
381: public String toString() {
382: return "Array memberOf";
383: }
384: }
385:
386: static class ArrayNotMemberOfEvaluator extends BaseEvaluator {
387: /**
388: *
389: */
390: private static final long serialVersionUID = 400L;
391: public final static Evaluator INSTANCE = new ArrayNotMemberOfEvaluator();
392:
393: private ArrayNotMemberOfEvaluator() {
394: super (ValueType.ARRAY_TYPE, Operator.NOTMEMBEROF);
395: }
396:
397: public boolean evaluate(InternalWorkingMemory workingMemory,
398: final Extractor extractor, final Object object1,
399: final FieldValue object2) {
400: final Object[] array = (Object[]) object2.getValue();
401: final Object value = extractor.getValue(workingMemory,
402: object1);
403: if (array == null)
404: return false;
405: return ArrayUtils.search(array, value) < 0;
406: }
407:
408: public boolean evaluateCachedRight(
409: InternalWorkingMemory workingMemory,
410: final VariableContextEntry context, final Object left) {
411: final Object[] array = (Object[]) context.declaration
412: .getExtractor().getValue(workingMemory, left);
413: final Object value = ((ObjectVariableContextEntry) context).right;
414: if (array == null)
415: return false;
416: return ArrayUtils.search(array, value) < 0;
417: }
418:
419: public boolean evaluateCachedLeft(
420: InternalWorkingMemory workingMemory,
421: final VariableContextEntry context, final Object right) {
422: final Object[] array = (Object[]) ((ObjectVariableContextEntry) context).left;
423: final Object value = context.extractor.getValue(
424: workingMemory, right);
425: if (array == null)
426: return false;
427: return ArrayUtils.search(array, value) < 0;
428: }
429:
430: public boolean evaluate(InternalWorkingMemory workingMemory,
431: final Extractor extractor1, final Object object1,
432: final Extractor extractor2, final Object object2) {
433: final Object[] array = (Object[]) extractor2.getValue(
434: workingMemory, object2);
435: final Object value = extractor1.getValue(workingMemory,
436: object1);
437:
438: if (array == null)
439: return false;
440: return ArrayUtils.search(array, value) < 0;
441: }
442:
443: public String toString() {
444: return "Array not memberOf";
445: }
446: }
447:
448: /**
449: * Utility functions for arrays
450: *
451: * @author etirelli
452: */
453: static final class ArrayUtils {
454:
455: public static final int search(Object[] array, Object value) {
456: int index = -1;
457: for (int i = 0; i < array.length; i++) {
458: if ((array[i] == null && value == null)
459: || (array[i] != null && array[i].equals(value))) {
460: index = i;
461: break;
462: }
463: }
464: return index;
465: }
466:
467: public static final int search(boolean[] array, boolean value) {
468: int index = -1;
469: for (int i = 0; i < array.length; i++) {
470: if (array[i] == value) {
471: index = i;
472: break;
473: }
474: }
475: return index;
476: }
477:
478: public static final int search(byte[] array, byte value) {
479: int index = -1;
480: for (int i = 0; i < array.length; i++) {
481: if (array[i] == value) {
482: index = i;
483: break;
484: }
485: }
486: return index;
487: }
488:
489: public static final int search(short[] array, short value) {
490: int index = -1;
491: for (int i = 0; i < array.length; i++) {
492: if (array[i] == value) {
493: index = i;
494: break;
495: }
496: }
497: return index;
498: }
499:
500: public static final int search(int[] array, int value) {
501: int index = -1;
502: for (int i = 0; i < array.length; i++) {
503: if (array[i] == value) {
504: index = i;
505: break;
506: }
507: }
508: return index;
509: }
510:
511: public static final int search(long[] array, long value) {
512: int index = -1;
513: for (int i = 0; i < array.length; i++) {
514: if (array[i] == value) {
515: index = i;
516: break;
517: }
518: }
519: return index;
520: }
521:
522: public static final int search(float[] array, float value) {
523: int index = -1;
524: for (int i = 0; i < array.length; i++) {
525: if (array[i] == value) {
526: index = i;
527: break;
528: }
529: }
530: return index;
531: }
532:
533: public static final int search(double[] array, double value) {
534: int index = -1;
535: for (int i = 0; i < array.length; i++) {
536: if (array[i] == value) {
537: index = i;
538: break;
539: }
540: }
541: return index;
542: }
543:
544: public static final int search(char[] array, char value) {
545: int index = -1;
546: for (int i = 0; i < array.length; i++) {
547: if (array[i] == value) {
548: index = i;
549: break;
550: }
551: }
552: return index;
553: }
554:
555: }
556:
557: }
|