001: /*
002: * Copyright 2002-2006 Peter Lin & RuleML.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://ruleml-dev.sourceforge.net/
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: *
016: */
017: package org.drools.facttemplates;
018:
019: import java.io.Serializable;
020: import java.util.Arrays;
021:
022: //import woolfel.engine.rule.Rule;
023:
024: /**
025: * @author Peter Lin
026: *
027: * Deffact is a concrete implementation of Fact interface. It is
028: * equivalent to deffact in CLIPS.
029: */
030: public class FactImpl implements Fact, Serializable {
031:
032: private static int hashCode(final Object[] array) {
033: final int PRIME = 31;
034: if (array == null) {
035: return 0;
036: }
037: int result = 1;
038: for (int index = 0; index < array.length; index++) {
039: result = PRIME
040: * result
041: + (array[index] == null ? 0 : array[index]
042: .hashCode());
043: }
044: return result;
045: }
046:
047: private FactTemplate factTemplate = null;
048: private Object[] values = null;
049: private int hashCode;
050:
051: /**
052: * the Fact id must be unique, since we use it for the indexes
053: */
054: private long id;
055:
056: /**
057: * this is the default constructor
058: * @param instance
059: * @param values
060: */
061: public FactImpl(final FactTemplate template, final Object[] values,
062: final long id) {
063: this .factTemplate = template;
064: this .values = values;
065: this .id = id;
066: }
067:
068: public FactImpl(final FactTemplate template, final long id) {
069: this .factTemplate = template;
070: this .values = new Object[template.getNumberOfFields()];
071: this .id = id;
072: }
073:
074: /**
075: * Method returns the value of the given slot at the
076: * id.
077: * @param id
078: * @return
079: */
080: public Object getFieldValue(final int index) {
081: return this .values[index];
082: }
083:
084: public Object getFieldValue(final String name) {
085: return this .values[this .factTemplate
086: .getFieldTemplateIndex(name)];
087: }
088:
089: public void setFieldValue(final String name, final Object value) {
090: setFieldValue(this .factTemplate.getFieldTemplateIndex(name),
091: value);
092: }
093:
094: public void setFieldValue(final int index, final Object value) {
095: this .values[index] = value;
096: }
097:
098: /**
099: * Return the long factId
100: */
101: public long getFactId() {
102: return this .id;
103: }
104:
105: /**
106: * this is used to reset the id, in the event an user tries to
107: * assert the same fact again, we reset the id to the existing one.
108: * @param fact
109: */
110: protected void resetId(final Fact fact) {
111: this .id = fact.getFactId();
112: }
113:
114: /**
115: * Return the deftemplate for the fact
116: */
117: public FactTemplate getFactTemplate() {
118: return this .factTemplate;
119: }
120:
121: public int hashCode() {
122: if (this .hashCode == 0) {
123: final int PRIME = 31;
124: int result = 1;
125: result = PRIME * result + this .factTemplate.hashCode();
126: result = PRIME * result + FactImpl.hashCode(this .values);
127: this .hashCode = result;
128:
129: }
130: return this .hashCode;
131: }
132:
133: public boolean equals(final Object object) {
134: if (this == object) {
135: return true;
136: }
137:
138: if (object == null || FactImpl.class != object.getClass()) {
139: return false;
140: }
141:
142: final FactImpl other = (FactImpl) object;
143:
144: if (!this .factTemplate.equals(other.factTemplate)) {
145: return false;
146: }
147:
148: if (!Arrays.equals(this .values, other.values)) {
149: return false;
150: }
151:
152: return true;
153: }
154: }
|