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 java.util.Collection;
020:
021: import org.drools.base.BaseEvaluator;
022: import org.drools.base.ShadowProxy;
023: import org.drools.base.ValueType;
024: import org.drools.common.InternalWorkingMemory;
025: import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
026: import org.drools.rule.VariableRestriction.VariableContextEntry;
027: import org.drools.spi.Evaluator;
028: import org.drools.spi.Extractor;
029: import org.drools.spi.FieldValue;
030:
031: /**
032: * This is the misc "bucket" evaluator factory for objects.
033: * It is fairly limited in operations,
034: * and what operations are available are dependent on the exact type.
035: *
036: * This supports "<" and ">" etc by requiring objects to implement the comparable interface.
037: * Of course, literals will not work with comparator, as it has no way
038: * of converting from literal to the appropriate type.
039: *
040: * @author Michael Neale
041: */
042: public class ObjectFactory implements EvaluatorFactory {
043:
044: private static final long serialVersionUID = 400L;
045: private static EvaluatorFactory INSTANCE = new ObjectFactory();
046:
047: private ObjectFactory() {
048:
049: }
050:
051: public static EvaluatorFactory getInstance() {
052: if (ObjectFactory.INSTANCE == null) {
053: ObjectFactory.INSTANCE = new ObjectFactory();
054: }
055: return ObjectFactory.INSTANCE;
056: }
057:
058: public Evaluator getEvaluator(final Operator operator) {
059: if (operator == Operator.EQUAL) {
060: return ObjectEqualEvaluator.INSTANCE;
061: } else if (operator == Operator.NOT_EQUAL) {
062: return ObjectNotEqualEvaluator.INSTANCE;
063: } else if (operator == Operator.LESS) {
064: return ObjectLessEvaluator.INSTANCE;
065: } else if (operator == Operator.LESS_OR_EQUAL) {
066: return ObjectLessOrEqualEvaluator.INSTANCE;
067: } else if (operator == Operator.GREATER) {
068: return ObjectGreaterEvaluator.INSTANCE;
069: } else if (operator == Operator.GREATER_OR_EQUAL) {
070: return ObjectGreaterOrEqualEvaluator.INSTANCE;
071: } else if (operator == Operator.CONTAINS) {
072: return ObjectContainsEvaluator.INSTANCE;
073: } else if (operator == Operator.EXCLUDES) {
074: return ObjectExcludesEvaluator.INSTANCE;
075: } else if (operator == Operator.NOT_CONTAINS) {
076: return ObjectExcludesEvaluator.INSTANCE; // 'not contains' and 'excludes' are synonyms
077: } else if (operator == Operator.MEMBEROF) {
078: return ObjectMemberOfEvaluator.INSTANCE;
079: } else if (operator == Operator.NOTMEMBEROF) {
080: return ObjectNotMemberOfEvaluator.INSTANCE;
081: } else {
082: throw new RuntimeException("Operator '" + operator
083: + "' does not exist for ObjectEvaluator");
084: }
085: }
086:
087: static class ObjectEqualEvaluator extends BaseEvaluator {
088: /**
089: *
090: */
091: private static final long serialVersionUID = 400L;
092: public final static Evaluator INSTANCE = new ObjectEqualEvaluator();
093:
094: private ObjectEqualEvaluator() {
095: super (ValueType.OBJECT_TYPE, Operator.EQUAL);
096: }
097:
098: public boolean evaluate(InternalWorkingMemory workingMemory,
099: final Extractor extractor, final Object object1,
100: final FieldValue object2) {
101: final Object value1 = extractor.getValue(workingMemory,
102: object1);
103: final Object value2 = object2.getValue();
104: if (value1 == null) {
105: return value2 == null;
106: }
107: if (value2 != null && value2 instanceof ShadowProxy) {
108: return value2.equals(value1);
109: }
110: return value1.equals(value2);
111: }
112:
113: public boolean evaluateCachedRight(
114: InternalWorkingMemory workingMemory,
115: final VariableContextEntry context, final Object left) {
116: final Object value = context.declaration.getExtractor()
117: .getValue(workingMemory, left);
118: if (value == null) {
119: return ((ObjectVariableContextEntry) context).right == null;
120: }
121: if (((ObjectVariableContextEntry) context).right != null
122: && ((ObjectVariableContextEntry) context).right instanceof ShadowProxy) {
123: return ((ObjectVariableContextEntry) context).right
124: .equals(value);
125: }
126: return value
127: .equals(((ObjectVariableContextEntry) context).right);
128: }
129:
130: public boolean evaluateCachedLeft(
131: InternalWorkingMemory workingMemory,
132: final VariableContextEntry context, final Object right) {
133: final Object value = context.extractor.getValue(
134: workingMemory, right);
135: if (((ObjectVariableContextEntry) context).left == null) {
136: return value == null;
137: }
138: if (value != null && value instanceof ShadowProxy) {
139: return value
140: .equals(((ObjectVariableContextEntry) context).left);
141: }
142: return ((ObjectVariableContextEntry) context).left
143: .equals(value);
144: }
145:
146: public boolean evaluate(InternalWorkingMemory workingMemory,
147: final Extractor extractor1, final Object object1,
148: final Extractor extractor2, final Object object2) {
149: final Object value1 = extractor1.getValue(workingMemory,
150: object1);
151: final Object value2 = extractor2.getValue(workingMemory,
152: object2);
153: if (value1 == null) {
154: return value2 == null;
155: }
156: if (value2 != null && value2 instanceof ShadowProxy) {
157: return value2.equals(value1);
158: }
159: return value1.equals(value2);
160: }
161:
162: public String toString() {
163: return "Object ==";
164: }
165:
166: }
167:
168: static class ObjectNotEqualEvaluator extends BaseEvaluator {
169: /**
170: *
171: */
172: private static final long serialVersionUID = 400L;
173: public final static Evaluator INSTANCE = new ObjectNotEqualEvaluator();
174:
175: private ObjectNotEqualEvaluator() {
176: super (ValueType.OBJECT_TYPE, Operator.NOT_EQUAL);
177: }
178:
179: public boolean evaluate(InternalWorkingMemory workingMemory,
180: final Extractor extractor, final Object object1,
181: final FieldValue object2) {
182: final Object value1 = extractor.getValue(workingMemory,
183: object1);
184: final Object value2 = object2.getValue();
185: if (value1 == null) {
186: return value2 != null;
187: }
188: if (value2 != null && value2 instanceof ShadowProxy) {
189: return !value2.equals(value1);
190: }
191: return !value1.equals(value2);
192: }
193:
194: public boolean evaluateCachedRight(
195: InternalWorkingMemory workingMemory,
196: final VariableContextEntry context, final Object left) {
197: final Object value = context.declaration.getExtractor()
198: .getValue(workingMemory, left);
199: if (value == null) {
200: return ((ObjectVariableContextEntry) context).right != null;
201: }
202: if (((ObjectVariableContextEntry) context).right != null
203: && ((ObjectVariableContextEntry) context).right instanceof ShadowProxy) {
204: return !((ObjectVariableContextEntry) context).right
205: .equals(value);
206: }
207: return !value
208: .equals(((ObjectVariableContextEntry) context).right);
209: }
210:
211: public boolean evaluateCachedLeft(
212: InternalWorkingMemory workingMemory,
213: final VariableContextEntry context, final Object right) {
214: final Object value = context.extractor.getValue(
215: workingMemory, right);
216: if (((ObjectVariableContextEntry) context).left == null) {
217: return value != null;
218: }
219: if (value != null && value instanceof ShadowProxy) {
220: return !value
221: .equals(((ObjectVariableContextEntry) context).left);
222: }
223: return !((ObjectVariableContextEntry) context).left
224: .equals(value);
225: }
226:
227: public boolean evaluate(InternalWorkingMemory workingMemory,
228: final Extractor extractor1, final Object object1,
229: final Extractor extractor2, final Object object2) {
230: final Object value1 = extractor1.getValue(workingMemory,
231: object1);
232: final Object value2 = extractor2.getValue(workingMemory,
233: object2);
234: if (value1 == null) {
235: return value2 != null;
236: }
237: if (value2 != null && value2 instanceof ShadowProxy) {
238: return !value2.equals(value1);
239: }
240: return !value1.equals(value2);
241: }
242:
243: public String toString() {
244: return "Object !=";
245: }
246: }
247:
248: static class ObjectLessEvaluator extends BaseEvaluator {
249: private static final long serialVersionUID = 400L;
250: public final static Evaluator INSTANCE = new ObjectLessEvaluator();
251:
252: private ObjectLessEvaluator() {
253: super (ValueType.OBJECT_TYPE, Operator.LESS);
254: }
255:
256: public boolean evaluate(InternalWorkingMemory workingMemory,
257: final Extractor extractor, final Object object1,
258: final FieldValue object2) {
259: if (extractor.isNullValue(workingMemory, object1)) {
260: return false;
261: }
262: final Comparable comp = (Comparable) extractor.getValue(
263: workingMemory, object1);
264: return comp.compareTo(object2.getValue()) < 0;
265: }
266:
267: public boolean evaluateCachedRight(
268: InternalWorkingMemory workingMemory,
269: final VariableContextEntry context, final Object left) {
270: if (context.rightNull) {
271: return false;
272: }
273: final Comparable comp = (Comparable) ((ObjectVariableContextEntry) context).right;
274: return comp.compareTo(context.declaration.getExtractor()
275: .getValue(workingMemory, left)) < 0;
276: }
277:
278: public boolean evaluateCachedLeft(
279: InternalWorkingMemory workingMemory,
280: final VariableContextEntry context, final Object right) {
281: if (context.extractor.isNullValue(workingMemory, right)) {
282: return false;
283: }
284: final Comparable comp = (Comparable) context.extractor
285: .getValue(workingMemory, right);
286: return comp
287: .compareTo(((ObjectVariableContextEntry) context).left) < 0;
288: }
289:
290: public boolean evaluate(InternalWorkingMemory workingMemory,
291: final Extractor extractor1, final Object object1,
292: final Extractor extractor2, final Object object2) {
293: if (extractor1.isNullValue(workingMemory, object1)) {
294: return false;
295: }
296: final Comparable comp = (Comparable) extractor1.getValue(
297: workingMemory, object1);
298: return comp.compareTo(extractor2.getValue(workingMemory,
299: object2)) < 0;
300: }
301:
302: public String toString() {
303: return "Object <";
304: }
305: }
306:
307: static class ObjectLessOrEqualEvaluator extends BaseEvaluator {
308: /**
309: *
310: */
311: private static final long serialVersionUID = 400L;
312: public final static Evaluator INSTANCE = new ObjectLessOrEqualEvaluator();
313:
314: private ObjectLessOrEqualEvaluator() {
315: super (ValueType.OBJECT_TYPE, Operator.LESS_OR_EQUAL);
316: }
317:
318: public boolean evaluate(InternalWorkingMemory workingMemory,
319: final Extractor extractor, final Object object1,
320: final FieldValue object2) {
321: if (extractor.isNullValue(workingMemory, object1)) {
322: return false;
323: }
324: final Comparable comp = (Comparable) extractor.getValue(
325: workingMemory, object1);
326: return comp.compareTo(object2.getValue()) <= 0;
327: }
328:
329: public boolean evaluateCachedRight(
330: InternalWorkingMemory workingMemory,
331: final VariableContextEntry context, final Object left) {
332: if (context.rightNull) {
333: return false;
334: }
335: final Comparable comp = (Comparable) ((ObjectVariableContextEntry) context).right;
336: return comp.compareTo(context.declaration.getExtractor()
337: .getValue(workingMemory, left)) <= 0;
338: }
339:
340: public boolean evaluateCachedLeft(
341: InternalWorkingMemory workingMemory,
342: final VariableContextEntry context, final Object right) {
343: if (context.extractor.isNullValue(workingMemory, right)) {
344: return false;
345: }
346: final Comparable comp = (Comparable) context.extractor
347: .getValue(workingMemory, right);
348: return comp
349: .compareTo(((ObjectVariableContextEntry) context).left) <= 0;
350: }
351:
352: public boolean evaluate(InternalWorkingMemory workingMemory,
353: final Extractor extractor1, final Object object1,
354: final Extractor extractor2, final Object object2) {
355: if (extractor1.isNullValue(workingMemory, object1)) {
356: return false;
357: }
358: final Comparable comp = (Comparable) extractor1.getValue(
359: workingMemory, object1);
360: return comp.compareTo(extractor2.getValue(workingMemory,
361: object2)) <= 0;
362: }
363:
364: public String toString() {
365: return "Object <=";
366: }
367: }
368:
369: static class ObjectGreaterEvaluator extends BaseEvaluator {
370: /**
371: *
372: */
373: private static final long serialVersionUID = 400L;
374: public final static Evaluator INSTANCE = new ObjectGreaterEvaluator();
375:
376: private ObjectGreaterEvaluator() {
377: super (ValueType.OBJECT_TYPE, Operator.GREATER);
378: }
379:
380: public boolean evaluate(InternalWorkingMemory workingMemory,
381: final Extractor extractor, final Object object1,
382: final FieldValue object2) {
383: if (extractor.isNullValue(workingMemory, object1)) {
384: return false;
385: }
386: final Comparable comp = (Comparable) extractor.getValue(
387: workingMemory, object1);
388: return comp.compareTo(object2.getValue()) > 0;
389: }
390:
391: public boolean evaluateCachedRight(
392: InternalWorkingMemory workingMemory,
393: final VariableContextEntry context, final Object left) {
394: if (context.rightNull) {
395: return false;
396: }
397: final Comparable comp = (Comparable) ((ObjectVariableContextEntry) context).right;
398: return comp.compareTo(context.declaration.getExtractor()
399: .getValue(workingMemory, left)) > 0;
400: }
401:
402: public boolean evaluateCachedLeft(
403: InternalWorkingMemory workingMemory,
404: final VariableContextEntry context, final Object right) {
405: if (context.extractor.isNullValue(workingMemory, right)) {
406: return false;
407: }
408: final Comparable comp = (Comparable) context.extractor
409: .getValue(workingMemory, right);
410: return comp
411: .compareTo(((ObjectVariableContextEntry) context).left) > 0;
412: }
413:
414: public boolean evaluate(InternalWorkingMemory workingMemory,
415: final Extractor extractor1, final Object object1,
416: final Extractor extractor2, final Object object2) {
417: if (extractor1.isNullValue(workingMemory, object1)) {
418: return false;
419: }
420: final Comparable comp = (Comparable) extractor1.getValue(
421: workingMemory, object1);
422: return comp.compareTo(extractor2.getValue(workingMemory,
423: object2)) > 0;
424: }
425:
426: public String toString() {
427: return "Object >";
428: }
429: }
430:
431: static class ObjectGreaterOrEqualEvaluator extends BaseEvaluator {
432: /**
433: *
434: */
435: private static final long serialVersionUID = 400L;
436: public final static Evaluator INSTANCE = new ObjectGreaterOrEqualEvaluator();
437:
438: private ObjectGreaterOrEqualEvaluator() {
439: super (ValueType.OBJECT_TYPE, Operator.GREATER_OR_EQUAL);
440: }
441:
442: public boolean evaluate(InternalWorkingMemory workingMemory,
443: final Extractor extractor, final Object object1,
444: final FieldValue object2) {
445: if (extractor.isNullValue(workingMemory, object1)) {
446: return false;
447: }
448: final Comparable comp = (Comparable) extractor.getValue(
449: workingMemory, object1);
450: return comp.compareTo(object2.getValue()) >= 0;
451: }
452:
453: public boolean evaluateCachedRight(
454: InternalWorkingMemory workingMemory,
455: final VariableContextEntry context, final Object left) {
456: if (context.rightNull) {
457: return false;
458: }
459: final Comparable comp = (Comparable) ((ObjectVariableContextEntry) context).right;
460: return comp.compareTo(context.declaration.getExtractor()
461: .getValue(workingMemory, left)) >= 0;
462: }
463:
464: public boolean evaluateCachedLeft(
465: InternalWorkingMemory workingMemory,
466: final VariableContextEntry context, final Object right) {
467: if (context.extractor.isNullValue(workingMemory, right)) {
468: return false;
469: }
470: final Comparable comp = (Comparable) context.extractor
471: .getValue(workingMemory, right);
472: return comp
473: .compareTo(((ObjectVariableContextEntry) context).left) >= 0;
474: }
475:
476: public boolean evaluate(InternalWorkingMemory workingMemory,
477: final Extractor extractor1, final Object object1,
478: final Extractor extractor2, final Object object2) {
479: if (extractor1.isNullValue(workingMemory, object1)) {
480: return false;
481: }
482: final Comparable comp = (Comparable) extractor1.getValue(
483: workingMemory, object1);
484: return comp.compareTo(extractor2.getValue(workingMemory,
485: object2)) >= 0;
486: }
487:
488: public String toString() {
489: return "Object >=";
490: }
491: }
492:
493: static class ObjectContainsEvaluator extends BaseEvaluator {
494: /**
495: *
496: */
497: private static final long serialVersionUID = 400L;
498: public final static Evaluator INSTANCE = new ObjectContainsEvaluator();
499:
500: private ObjectContainsEvaluator() {
501: super (ValueType.OBJECT_TYPE, Operator.CONTAINS);
502: }
503:
504: public boolean evaluate(InternalWorkingMemory workingMemory,
505: final Extractor extractor, final Object object1,
506: final FieldValue object2) {
507: final Object value = object2.getValue();
508: final Collection col = (Collection) extractor.getValue(
509: workingMemory, object1);
510: return (col == null) ? false : col.contains(value);
511: }
512:
513: public boolean evaluateCachedRight(
514: InternalWorkingMemory workingMemory,
515: final VariableContextEntry context, final Object left) {
516: final Object value = context.declaration.getExtractor()
517: .getValue(workingMemory, left);
518: final Collection col = (Collection) ((ObjectVariableContextEntry) context).right;
519: return (col == null) ? false : col.contains(value);
520: }
521:
522: public boolean evaluateCachedLeft(
523: InternalWorkingMemory workingMemory,
524: final VariableContextEntry context, final Object right) {
525: final Object value = ((ObjectVariableContextEntry) context).left;
526: final Collection col = (Collection) context.extractor
527: .getValue(workingMemory, right);
528: return (col == null) ? false : col.contains(value);
529: }
530:
531: public boolean evaluate(InternalWorkingMemory workingMemory,
532: final Extractor extractor1, final Object object1,
533: final Extractor extractor2, final Object object2) {
534: final Object value = extractor2.getValue(workingMemory,
535: object2);
536: final Collection col = (Collection) extractor1.getValue(
537: workingMemory, object1);
538: return (col == null) ? false : col.contains(value);
539: }
540:
541: public String toString() {
542: return "Object contains";
543: }
544: }
545:
546: static class ObjectExcludesEvaluator extends BaseEvaluator {
547: /**
548: *
549: */
550: private static final long serialVersionUID = 400L;
551: public final static Evaluator INSTANCE = new ObjectExcludesEvaluator();
552:
553: private ObjectExcludesEvaluator() {
554: super (ValueType.OBJECT_TYPE, Operator.EXCLUDES);
555: }
556:
557: public boolean evaluate(InternalWorkingMemory workingMemory,
558: final Extractor extractor, final Object object1,
559: final FieldValue object2) {
560: final Object value = object2.getValue();
561: final Collection col = (Collection) extractor.getValue(
562: workingMemory, object1);
563: return !col.contains(value);
564: }
565:
566: public boolean evaluateCachedRight(
567: InternalWorkingMemory workingMemory,
568: final VariableContextEntry context, final Object left) {
569: final Object value = context.declaration.getExtractor()
570: .getValue(workingMemory, left);
571: final Collection col = (Collection) ((ObjectVariableContextEntry) context).right;
572: return !col.contains(value);
573: }
574:
575: public boolean evaluateCachedLeft(
576: InternalWorkingMemory workingMemory,
577: final VariableContextEntry context, final Object right) {
578: final Object value = ((ObjectVariableContextEntry) context).left;
579: final Collection col = (Collection) context.extractor
580: .getValue(workingMemory, right);
581: return !col.contains(value);
582: }
583:
584: public boolean evaluate(InternalWorkingMemory workingMemory,
585: final Extractor extractor1, final Object object1,
586: final Extractor extractor2, final Object object2) {
587: final Object value = extractor2.getValue(workingMemory,
588: object2);
589: final Collection col = (Collection) extractor1.getValue(
590: workingMemory, object1);
591: return !col.contains(value);
592: }
593:
594: public String toString() {
595: return "Object excludes";
596: }
597: }
598:
599: static class ObjectMemberOfEvaluator extends BaseMemberOfEvaluator {
600:
601: private static final long serialVersionUID = 400L;
602: public final static Evaluator INSTANCE = new ObjectMemberOfEvaluator();
603:
604: private ObjectMemberOfEvaluator() {
605: super (ValueType.OBJECT_TYPE, Operator.MEMBEROF);
606: }
607:
608: public String toString() {
609: return "Object memberOf";
610: }
611: }
612:
613: static class ObjectNotMemberOfEvaluator extends
614: BaseNotMemberOfEvaluator {
615:
616: private static final long serialVersionUID = 400L;
617: public final static Evaluator INSTANCE = new ObjectNotMemberOfEvaluator();
618:
619: private ObjectNotMemberOfEvaluator() {
620: super (ValueType.OBJECT_TYPE, Operator.NOTMEMBEROF);
621: }
622:
623: public String toString() {
624: return "Object not memberOf";
625: }
626: }
627:
628: }
|