package org.drools.rule;
/*
* $Id: Declaration.java,v 1.1 2005/07/26 01:06:31 mproctor Exp $
*
* Copyright 2001-2003 (C) The Werken Company. All Rights Reserved.
*
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain copyright statements and
* notices. Redistributions must also contain a copy of this document.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name "drools" must not be used to endorse or promote products derived
* from this Software without prior written permission of The Werken Company.
* For written permission, please contact bob@werken.com.
*
* 4. Products derived from this Software may not be called "drools" nor may
* "drools" appear in their names without prior written permission of The Werken
* Company. "drools" is a trademark of The Werken Company.
*
* 5. Due credit should be given to The Werken Company. (http://werken.com/)
*
* THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE WERKEN COMPANY OR ITS CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import org.drools.RuntimeDroolsException;
import org.drools.base.ValueType;
import org.drools.common.InternalWorkingMemory;
import org.drools.spi.AcceptsReadAccessor;
import org.drools.spi.InternalReadAccessor;
/**
* @author <a href="mailto:mark.proctor@jboss.com">Mark Proctor</a>
* @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
* @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris </a>
*
*/
public class Declaration
implements
Externalizable,
AcceptsReadAccessor,
Cloneable {
// ------------------------------------------------------------
// Instance members
// ------------------------------------------------------------
/**
*
*/
private static final long serialVersionUID = 510l;
/** The identifier for the variable. */
private String identifier;
private InternalReadAccessor readAccessor;
private Pattern pattern;
private boolean internalFact;
// ------------------------------------------------------------
// Constructors
// ------------------------------------------------------------
public Declaration() {
this( null,
null,
null );
}
/**
* Construct.
*
* @param identifier
* The name of the variable.
* @param objectType
* The type of this variable declaration.
* @param order
* The index within a rule.
*/
public Declaration(final String identifier,
final Pattern pattern) {
this( identifier,
null,
pattern,
false );
}
/**
* Construct.
*
* @param identifier
* The name of the variable.
* @param objectType
* The type of this variable declaration.
* @param order
* The index within a rule.
*/
public Declaration(final String identifier,
final InternalReadAccessor extractor,
final Pattern pattern) {
this( identifier,
extractor,
pattern,
false );
}
/**
* Construct.
*
* @param identifier
* The name of the variable.
* @param objectType
* The type of this variable declaration.
* @param order
* The index within a rule.
* @param internalFact
* True if this is an internal fact created by the engine, like a collection result
* of a collect CE
*/
public Declaration(final String identifier,
final InternalReadAccessor extractor,
final Pattern pattern,
final boolean internalFact) {
this.identifier = identifier;
this.readAccessor = extractor;
this.pattern = pattern;
this.internalFact = internalFact;
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
identifier = (String) in.readObject();
readAccessor = (InternalReadAccessor) in.readObject();
pattern = (Pattern) in.readObject();
internalFact = in.readBoolean();
}
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( identifier );
out.writeObject( readAccessor );
out.writeObject( pattern );
out.writeBoolean( internalFact );
}
public void setReadAccessor(InternalReadAccessor readAccessor) {
this.readAccessor = readAccessor;
}
// ------------------------------------------------------------
// Instance methods
// ------------------------------------------------------------
/**
* Retrieve the variable's identifier.
*
* @return The variable's identifier.
*/
public String getIdentifier() {
return this.identifier;
}
/**
* Retrieve the <code>ValueType</code>.
*
* @return The ValueType.
*/
public ValueType getValueType() {
return this.readAccessor.getValueType();
}
/**
* Returns the index of the pattern
*
* @return the pattern
*/
public Pattern getPattern() {
return this.pattern;
}
public void setPattern(final Pattern pattern) {
this.pattern = pattern;
}
/**
* Returns true if this declaration is a pattern declaration
* @return
*/
public boolean isPatternDeclaration() {
return this.pattern != null && this.pattern.getDeclaration() == this;
}
/**
* Returns the Extractor expression
*
* @return
*/
public InternalReadAccessor getExtractor() {
return this.readAccessor;
}
public Object getValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getValue( workingMemory,
object );
}
public Object getNonShadowedValue(InternalWorkingMemory workingMemory,
final Object object) {
Object result = this.readAccessor.getValue( workingMemory,
object );
if ( this.isInternalFact() && result instanceof Collection ) {
try {
Collection newCol = (Collection) result.getClass().newInstance();
for ( Iterator it = ((Collection) result).iterator(); it.hasNext(); ) {
Object element = it.next();
newCol.add( element );
}
return newCol;
} catch ( InstantiationException e ) {
// nothing we can do, so just return the resulting object
} catch ( IllegalAccessException e ) {
// TODO Auto-generated catch block
}
}
return result;
}
public char getCharValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getCharValue( workingMemory,
object );
}
public int getIntValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getIntValue( workingMemory,
object );
}
public byte getByteValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getByteValue( workingMemory,
object );
}
public short getShortValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getShortValue( workingMemory,
object );
}
public long getLongValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getLongValue( workingMemory,
object );
}
public float getFloatValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getFloatValue( workingMemory,
object );
}
public double getDoubleValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getDoubleValue( workingMemory,
object );
}
public boolean getBooleanValue(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getBooleanValue( workingMemory,
object );
}
public int getHashCode(InternalWorkingMemory workingMemory,
final Object object) {
return this.readAccessor.getHashCode( workingMemory,
object );
}
public boolean isGlobal() {
if( this.readAccessor == null ) return false;
return this.readAccessor.isGlobal();
}
public Method getNativeReadMethod() {
if ( this.isPatternDeclaration() && this.isInternalFact() ) {
try {
return this.getClass().getDeclaredMethod( "getNonShadowedValue",
new Class[]{InternalWorkingMemory.class, Object.class} );
} catch ( final Exception e ) {
throw new RuntimeDroolsException( "This is a bug. Please report to development team: " + e.getMessage(),
e );
}
}
return this.readAccessor.getNativeReadMethod();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public String toString() {
return "(" + this.readAccessor.getValueType() + ") " + this.identifier;
}
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * this.pattern.getOffset();
result = PRIME * this.readAccessor.hashCode();
result = PRIME * this.identifier.hashCode();
return result;
}
public boolean equals(final Object object) {
if ( this == object ) {
return true;
}
if ( object == null || getClass() != object.getClass() ) {
return false;
}
final Declaration other = (Declaration) object;
return this.pattern.getOffset() == other.pattern.getOffset() && this.identifier.equals( other.identifier ) && this.readAccessor.equals( other.readAccessor );
}
protected boolean isInternalFact() {
return internalFact;
}
public Object clone() {
return new Declaration( this.identifier,
this.readAccessor,
this.pattern );
}
}