001: package org.drools.common;
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.io.Serializable;
020: import java.util.ArrayList;
021: import java.util.List;
022:
023: import org.drools.base.ShadowProxy;
024:
025: /**
026: * Upon instantiation the EqualityKey caches the first Object's hashCode
027: * this can never change. The EqualityKey has an internal datastructure
028: * which references all the handles which are equal. It also records
029: * Whether the referenced facts are JUSTIFIED or STATED
030: *
031: * @author <a href="mailto:mark.proctor@jboss.com">Mark Proctor</a>
032: *
033: */
034: public class EqualityKey implements Serializable {
035: public final static int STATED = 1;
036: public final static int JUSTIFIED = 2;
037:
038: /** this is an optimisation so single stated equalities can tracked without the overhead of an ArrayList */
039: private InternalFactHandle handle;
040:
041: /** this is always lazily maintainned and deleted when empty to minimise memory consumption */
042: private List instances;
043:
044: /** This is cached in the constructor from the first added Object */
045: private final int hashCode;
046:
047: /** Tracks whether this Fact is Stated or Justified */
048: private int status;
049:
050: public EqualityKey(final InternalFactHandle handle) {
051: this .handle = handle;
052: this .hashCode = handle.getObjectHashCode();
053: }
054:
055: public EqualityKey(final InternalFactHandle handle, final int status) {
056: this .handle = handle;
057: this .hashCode = handle.getObjectHashCode();
058: this .status = status;
059: }
060:
061: public InternalFactHandle getFactHandle() {
062: return this .handle;
063: }
064:
065: public List getOtherFactHandle() {
066: return this .instances;
067: }
068:
069: public void addFactHandle(final InternalFactHandle handle) {
070: if (this .instances == null) {
071: this .instances = new ArrayList();
072: }
073: this .instances.add(handle);
074: }
075:
076: public void removeFactHandle(final InternalFactHandle handle) {
077: if (this .handle == handle) {
078: if (this .instances == null) {
079: this .handle = null;
080: } else {
081: this .handle = (InternalFactHandle) this .instances
082: .remove(0);
083: if (this .instances.isEmpty()) {
084: this .instances = null;
085: }
086: }
087: } else {
088: this .instances.remove(handle);
089: if (this .instances.isEmpty()) {
090: this .instances = null;
091: }
092: }
093: }
094:
095: /**
096: * @return the status
097: */
098: public int getStatus() {
099: return this .status;
100: }
101:
102: /**
103: * @param status the status to set
104: */
105: public void setStatus(final int status) {
106: this .status = status;
107: }
108:
109: public int size() {
110: if (this .instances != null) {
111: return this .instances.size() + 1;
112: } else {
113: return (this .handle != null) ? 1 : 0;
114: }
115: }
116:
117: public boolean isEmpty() {
118: return (this .handle == null);
119: }
120:
121: public String toString() {
122: String str = null;
123: switch (this .status) {
124: case 1:
125: str = "STATED";
126: break;
127: case 2:
128: str = "JUSTIFIED";
129: break;
130: }
131: return "[FactStatus status=" + this .status + "]";
132: }
133:
134: /**
135: * Returns the cached hashCode
136: * @see java.lang.Object#hashCode()
137: */
138: public int hashCode() {
139: return this .hashCode;
140: }
141:
142: /**
143: * Equality for the EqualityKey means two things. It returns
144: * true if the object is also an EqualityKey the of the same
145: * the same identity as this. It also returns true if the object
146: * is equal to the head FactHandle's referenced Object.
147: */
148: public boolean equals(final Object object) {
149: if (object == null) {
150: return false;
151: }
152:
153: if (object instanceof EqualityKey) {
154: return this == object;
155: }
156:
157: return (this.handle.getObject().equals(object));
158: }
159:
160: }
|