001: package org.drools.conflict;
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.common.InternalFactHandle;
020: import org.drools.spi.Activation;
021: import org.drools.spi.ConflictResolver;
022:
023: /**
024: * <code>ConflictResolver</code> that uses the mostRecentFactTimeStamp of
025: * rules to resolve conflict.
026: *
027: * @see #getInstance
028: * @see org.drools.spi.Tuple#getMostRecentFactTimeStamp
029: *
030: * @author <a href="mailto:bob@werken.com">bob mcwhirter </a>
031: * @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris </a>
032: */
033: public class RecencyConflictResolver extends AbstractConflictResolver {
034: // ----------------------------------------------------------------------
035: // Class members
036: // ----------------------------------------------------------------------
037:
038: /**
039: *
040: */
041: private static final long serialVersionUID = 400L;
042: /** Singleton instance. */
043: private static final RecencyConflictResolver INSTANCE = new RecencyConflictResolver();
044:
045: // ----------------------------------------------------------------------
046: // Class methods
047: // ----------------------------------------------------------------------
048:
049: /**
050: * Retrieve the singleton instance.
051: *
052: * @return The singleton instance.
053: */
054: public static ConflictResolver getInstance() {
055: return RecencyConflictResolver.INSTANCE;
056: }
057:
058: // ----------------------------------------------------------------------
059: // Constructors
060: // ----------------------------------------------------------------------
061:
062: /**
063: * Construct.
064: */
065: public RecencyConflictResolver() {
066: // intentionally left blank
067: }
068:
069: // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
070:
071: /**
072: * @see ConflictResolver
073: */
074: public int compare(final Activation lhs, final Activation rhs) {
075: final InternalFactHandle[] lFacts = lhs.getTuple()
076: .getFactHandles();
077: final InternalFactHandle[] rFacts = rhs.getTuple()
078: .getFactHandles();
079:
080: InternalFactHandle leftMostRecent = getMostRecentFact(lFacts);
081: InternalFactHandle rightMostRecent = getMostRecentFact(rFacts);
082:
083: final int lastIndex = (lFacts.length < rFacts.length) ? lFacts.length
084: : rFacts.length;
085:
086: if (leftMostRecent.getRecency() == rightMostRecent.getRecency()
087: && lastIndex > 1) {
088:
089: for (int i = 0; i < lastIndex; i++) {
090: leftMostRecent = getMostRecentFact(lFacts,
091: leftMostRecent);
092: rightMostRecent = getMostRecentFact(rFacts,
093: rightMostRecent);
094: if (leftMostRecent == null || rightMostRecent == null) {
095: if (leftMostRecent == null
096: && rightMostRecent != null) {
097: return (int) rightMostRecent.getRecency();
098: }
099: } else if (leftMostRecent.getRecency() != rightMostRecent
100: .getRecency()) {
101: return (int) (rightMostRecent.getRecency() - leftMostRecent
102: .getRecency());
103: }
104: }
105: } else {
106: return (int) (rightMostRecent.getRecency() - leftMostRecent
107: .getRecency());
108: }
109:
110: return rFacts.length - lFacts.length;
111: }
112:
113: private InternalFactHandle getMostRecentFact(
114: final InternalFactHandle[] handles) {
115: InternalFactHandle mostRecent = handles[0];
116: for (int i = 1; i < handles.length; i++) {
117: final InternalFactHandle eachHandle = handles[i];
118:
119: if (eachHandle.getRecency() > mostRecent.getRecency()) {
120: mostRecent = eachHandle;
121: }
122: }
123: return mostRecent;
124: }
125:
126: private InternalFactHandle getMostRecentFact(
127: final InternalFactHandle[] handles,
128: final InternalFactHandle handle) {
129: InternalFactHandle mostRecent = null;
130:
131: for (int i = 0; i < handles.length; i++) {
132: final InternalFactHandle eachHandle = handles[i];
133:
134: if (mostRecent == null
135: && eachHandle.getRecency() < handle.getRecency()) {
136: mostRecent = eachHandle;
137: }
138:
139: if (mostRecent != null
140: && eachHandle.getRecency() > mostRecent
141: .getRecency()
142: && eachHandle.getRecency() < handle.getRecency()) {
143: mostRecent = eachHandle;
144: }
145: }
146: return mostRecent;
147: }
148:
149: }
|