001: package org.drools.rule;
002:
003: import java.util.Arrays;
004: import java.util.HashSet;
005: import java.util.Set;
006:
007: import org.drools.common.InternalFactHandle;
008: import org.drools.common.InternalWorkingMemory;
009: import org.drools.reteoo.ReteTuple;
010: import org.drools.spi.Restriction;
011:
012: public abstract class AbstractCompositeRestriction implements
013: Restriction {
014:
015: private static final long serialVersionUID = 400L;
016:
017: protected final Restriction[] restrictions;
018: protected final CompositeContextEntry contextEntry;
019:
020: public AbstractCompositeRestriction(final Restriction[] restriction) {
021: this .restrictions = restriction;
022: this .contextEntry = new CompositeContextEntry(this .restrictions);
023: }
024:
025: public Declaration[] getRequiredDeclarations() {
026: // Iterate all restrictions building up a unique list of declarations
027: // No need to cache, as this should only be called once at build time
028: final Set set = new HashSet();
029: for (int i = 0, ilength = this .restrictions.length; i < ilength; i++) {
030: final Declaration[] declarations = this .restrictions[i]
031: .getRequiredDeclarations();
032: for (int j = 0, jlength = declarations.length; j < jlength; j++) {
033: set.add(declarations[j]);
034: }
035: }
036:
037: return (Declaration[]) set.toArray(new Declaration[set.size()]);
038: }
039:
040: private static int hashCode(final Object[] array) {
041: final int PRIME = 31;
042: if (array == null) {
043: return 0;
044: }
045: int result = 1;
046: for (int index = 0; index < array.length; index++) {
047: result = PRIME
048: * result
049: + (array[index] == null ? 0 : array[index]
050: .hashCode());
051: }
052: return result;
053: }
054:
055: public int hashCode() {
056: final int PRIME = 31;
057: int result = 1;
058: result = PRIME
059: * result
060: + AbstractCompositeRestriction
061: .hashCode(this .restrictions);
062: return result;
063: }
064:
065: public boolean equals(final Object obj) {
066: if (this == obj) {
067: return true;
068: }
069:
070: if (obj == null || obj instanceof AbstractCompositeRestriction) {
071: return false;
072: }
073:
074: final AbstractCompositeRestriction other = (AbstractCompositeRestriction) obj;
075: if (!Arrays.equals(this .restrictions, other.restrictions)) {
076: return false;
077: }
078: return true;
079: }
080:
081: public ContextEntry getContextEntry() {
082: return this .contextEntry;
083: }
084:
085: public static class CompositeContextEntry implements ContextEntry {
086: public ContextEntry[] contextEntries;
087:
088: private ContextEntry entry;
089:
090: public CompositeContextEntry(final Restriction[] restrictions) {
091: contextEntries = new ContextEntry[restrictions.length];
092: for (int i = 0; i < restrictions.length; i++) {
093: contextEntries[i] = restrictions[i].getContextEntry();
094: }
095: }
096:
097: public ContextEntry getNext() {
098: return this .entry;
099: }
100:
101: public void setNext(final ContextEntry entry) {
102: this .entry = entry;
103: }
104:
105: public void updateFromFactHandle(
106: final InternalWorkingMemory workingMemory,
107: final InternalFactHandle handle) {
108: for (int i = 0, length = this .contextEntries.length; i < length; i++) {
109: this .contextEntries[i].updateFromFactHandle(
110: workingMemory, handle);
111: }
112: }
113:
114: public void updateFromTuple(
115: final InternalWorkingMemory workingMemory,
116: final ReteTuple tuple) {
117: for (int i = 0, length = this.contextEntries.length; i < length; i++) {
118: this.contextEntries[i].updateFromTuple(workingMemory,
119: tuple);
120: }
121: }
122:
123: }
124:
125: }
|