001: package org.drools.base;
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.IOException;
020: import java.io.ObjectInputStream;
021: import java.lang.reflect.Method;
022:
023: import org.drools.RuntimeDroolsException;
024: import org.drools.common.InternalWorkingMemory;
025: import org.drools.spi.FieldExtractor;
026: import org.drools.util.ClassUtils;
027:
028: /**
029: * This provides access to fields, and what their numerical index/object type is.
030: * This is basically a wrapper class around dynamically generated subclasses of
031: * BaseClassFieldExtractor,
032: * which allows serialization by regenerating the accessor classes
033: * when needed.
034: *
035: * @author Michael Neale
036: */
037: public class ClassFieldExtractor implements FieldExtractor {
038: /**
039: *
040: */
041: private static final long serialVersionUID = 400L;
042: private String fieldName;
043: private Class clazz;
044: private transient FieldExtractor extractor;
045:
046: public ClassFieldExtractor(final Class clazz, final String fieldName) {
047: this (clazz, fieldName, null);
048: }
049:
050: public ClassFieldExtractor(final Class clazz,
051: final String fieldName, final ClassLoader classLoader) {
052: this .clazz = clazz;
053: this .fieldName = fieldName;
054: init(classLoader);
055: }
056:
057: private void readObject(final ObjectInputStream is)
058: throws ClassNotFoundException, IOException, Exception {
059: //always perform the default de-serialization first
060: is.defaultReadObject();
061:
062: // do not create the extractor yet, readResolver will do this, as it stops duplicate bytecode generation.
063: }
064:
065: private Object readResolve() {
066: // always return the value from the cache
067: return ClassFieldExtractorCache.getExtractor(this .clazz,
068: this .fieldName, this .clazz.getClassLoader());
069: }
070:
071: public void init(final ClassLoader classLoader) {
072: try {
073: this .extractor = ClassFieldExtractorFactory
074: .getClassFieldExtractor(this .clazz, this .fieldName,
075: classLoader);
076: } catch (final Exception e) {
077: throw new RuntimeDroolsException(e);
078: }
079: }
080:
081: public int getIndex() {
082: return this .extractor.getIndex();
083: }
084:
085: public String getFieldName() {
086: return this .fieldName;
087: }
088:
089: public Object getValue(InternalWorkingMemory workingMemory,
090: final Object object) {
091: return this .extractor.getValue(workingMemory, object);
092: }
093:
094: public ValueType getValueType() {
095: return this .extractor.getValueType();
096: }
097:
098: public Class getExtractToClass() {
099: return this .extractor.getExtractToClass();
100: }
101:
102: public String getExtractToClassName() {
103: return ClassUtils.canonicalName(this .extractor
104: .getExtractToClass());
105: }
106:
107: public String toString() {
108: return "[ClassFieldExtractor class=" + this .clazz + " field="
109: + this .fieldName + "]";
110: }
111:
112: public int hashCode() {
113: return getValueType().hashCode() * 17 + getIndex();
114: }
115:
116: public boolean equals(final Object object) {
117: if (this == object) {
118: return true;
119: }
120:
121: if (object == null || !(object instanceof ClassFieldExtractor)) {
122: return false;
123: }
124:
125: final ClassFieldExtractor other = (ClassFieldExtractor) object;
126:
127: return this .extractor.getValueType() == other.getValueType()
128: && this .extractor.getIndex() == other.getIndex();
129: }
130:
131: public boolean getBooleanValue(InternalWorkingMemory workingMemory,
132: final Object object) {
133: return this .extractor.getBooleanValue(workingMemory, object);
134: }
135:
136: public byte getByteValue(InternalWorkingMemory workingMemory,
137: final Object object) {
138: return this .extractor.getByteValue(workingMemory, object);
139: }
140:
141: public char getCharValue(InternalWorkingMemory workingMemory,
142: final Object object) {
143: return this .extractor.getCharValue(workingMemory, object);
144: }
145:
146: public double getDoubleValue(InternalWorkingMemory workingMemory,
147: final Object object) {
148: return this .extractor.getDoubleValue(workingMemory, object);
149: }
150:
151: public float getFloatValue(InternalWorkingMemory workingMemory,
152: final Object object) {
153: return this .extractor.getFloatValue(workingMemory, object);
154: }
155:
156: public int getIntValue(InternalWorkingMemory workingMemory,
157: final Object object) {
158: return this .extractor.getIntValue(workingMemory, object);
159: }
160:
161: public long getLongValue(InternalWorkingMemory workingMemory,
162: final Object object) {
163: return this .extractor.getLongValue(workingMemory, object);
164: }
165:
166: public short getShortValue(InternalWorkingMemory workingMemory,
167: final Object object) {
168: return this .extractor.getShortValue(workingMemory, object);
169: }
170:
171: public boolean isNullValue(InternalWorkingMemory workingMemory,
172: final Object object) {
173: return this .extractor.isNullValue(workingMemory, object);
174: }
175:
176: public Method getNativeReadMethod() {
177: return this .extractor.getNativeReadMethod();
178: }
179:
180: public int getHashCode(InternalWorkingMemory workingMemory,
181: final Object object) {
182: return this .extractor.getHashCode(workingMemory, object);
183: }
184:
185: public boolean isGlobal() {
186: return false;
187: }
188: }
|