/* * Copyright 2015 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.core.rule; import org.drools.core.WorkingMemory; import org.drools.core.base.accumulators.MVELAccumulatorFunctionExecutor; import org.drools.core.common.InternalFactHandle; import org.drools.core.spi.Accumulator; import org.drools.core.spi.CompiledInvoker; import org.drools.core.spi.Tuple; import org.drools.core.spi.Wireable; import org.kie.internal.security.KiePolicyHelper; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; import java.util.Arrays; public class SingleAccumulate extends Accumulate { private Accumulator accumulator; public SingleAccumulate() { } public SingleAccumulate(final RuleConditionElement source, final Declaration[] requiredDeclarations ) { super(source, requiredDeclarations); } public SingleAccumulate(final RuleConditionElement source, final Declaration[] requiredDeclarations, final Accumulator accumulator ) { super(source, requiredDeclarations); this.accumulator = accumulator; } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { super.readExternal(in); this.accumulator = (Accumulator) in.readObject(); } public void writeExternal(ObjectOutput out) throws IOException { super.writeExternal(out); if ( accumulator instanceof CompiledInvoker) { out.writeObject( null ); } else { out.writeObject( accumulator ); } } public boolean isMultiFunction() { return false; } public Accumulator[] getAccumulators() { return new Accumulator[] { this.accumulator }; } public Serializable createContext() { return this.accumulator.createContext(); } public void init(final Object workingMemoryContext, final Object context, final Tuple leftTuple, final WorkingMemory workingMemory) { try { this.accumulator.init( workingMemoryContext, context, leftTuple, this.requiredDeclarations, workingMemory ); } catch ( final Exception e ) { throw new RuntimeException( e ); } } public void accumulate(final Object workingMemoryContext, final Object context, final Tuple leftTuple, final InternalFactHandle handle, final WorkingMemory workingMemory) { try { this.accumulator.accumulate( workingMemoryContext, context, leftTuple, handle, this.requiredDeclarations, getInnerDeclarationCache(), workingMemory ); } catch ( final Exception e ) { throw new RuntimeException( e ); } } public void reverse(final Object workingMemoryContext, final Object context, final Tuple leftTuple, final InternalFactHandle handle, final WorkingMemory workingMemory) { try { this.accumulator.reverse( workingMemoryContext, context, leftTuple, handle, this.requiredDeclarations, getInnerDeclarationCache(), workingMemory ); } catch ( final Exception e ) { throw new RuntimeException( e ); } } public boolean supportsReverse() { return this.accumulator.supportsReverse(); } public Object getResult(final Object workingMemoryContext, final Object context, final Tuple leftTuple, final WorkingMemory workingMemory) { try { return this.accumulator.getResult( workingMemoryContext, context, leftTuple, this.requiredDeclarations, workingMemory ); } catch ( final Exception e ) { throw new RuntimeException( e ); } } public SingleAccumulate clone() { RuleConditionElement clonedSource = source instanceof GroupElement ? ((GroupElement) source).cloneOnlyGroup() : source.clone(); SingleAccumulate clone = new SingleAccumulate( clonedSource, this.requiredDeclarations, this.accumulator ); registerClone(clone); return clone; } protected void replaceAccumulatorDeclaration(Declaration declaration, Declaration resolved) { if (accumulator instanceof MVELAccumulatorFunctionExecutor) { ( (MVELAccumulatorFunctionExecutor) accumulator ).replaceDeclaration( declaration, resolved ); } } public Object createWorkingMemoryContext() { return this.accumulator.createWorkingMemoryContext(); } public final class Wirer implements Wireable, Serializable { private static final long serialVersionUID = -9072646735174734614L; public void wire( Object object ) { Accumulator acc = KiePolicyHelper.isPolicyEnabled() ? new Accumulator.SafeAccumulator((Accumulator) object) : (Accumulator) object; accumulator = acc; for ( Accumulate clone : cloned ) { ((SingleAccumulate)clone).accumulator = acc; } } } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + accumulator.hashCode(); result = prime * result + Arrays.hashCode( requiredDeclarations ); result = prime * result + ((source == null) ? 0 : source.hashCode()); return result; } public boolean equals(Object obj) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; SingleAccumulate other = (SingleAccumulate) obj; if ( !accumulator.equals( other.accumulator ) ) return false; if ( !Arrays.equals( requiredDeclarations, other.requiredDeclarations ) ) return false; if ( source == null ) { if ( other.source != null ) return false; } else if ( !source.equals( other.source ) ) return false; return true; } }