package org.drools.rule.builder; import java.util.ArrayList; import java.util.List; import org.drools.base.ArrayElements; import org.drools.base.ClassObjectType; import org.drools.base.extractors.ArrayElementReader; import org.drools.base.extractors.SelfReferenceClassFieldReader; import org.drools.lang.descr.LiteralDescr; import org.drools.lang.descr.BaseDescr; import org.drools.lang.descr.PatternDescr; import org.drools.lang.descr.VariableDescr; import org.drools.rule.Declaration; import org.drools.rule.Pattern; import org.drools.rule.Query; import org.drools.rule.QueryElement; import org.drools.rule.Rule; import org.drools.rule.RuleConditionElement; import org.drools.rule.Variable; import org.drools.spi.InternalReadAccessor; import org.drools.spi.ObjectType; public class QueryElementBuilder implements RuleConditionBuilder { public RuleConditionElement build(RuleBuildContext context, BaseDescr descr) { return this.build( context, descr, null ); } public RuleConditionElement build(RuleBuildContext context, BaseDescr descr, Pattern prefixPattern) { PatternDescr patternDescr = (PatternDescr) descr; Query query = (Query) context.getPkg().getRule( patternDescr.getObjectType() ); Declaration[] params = query.getParameters(); List<BaseDescr> args = (List<BaseDescr>) patternDescr.getDescrs(); List<Integer> declrIndexes = new ArrayList<Integer>(); List<Integer> varIndexes = new ArrayList<Integer>(); List<Object> arguments = new ArrayList<Object>(); List<Declaration> requiredDeclarations = new ArrayList<Declaration>(); ObjectType argsObjectType = new ClassObjectType( Object[].class ); InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class, "this"); Pattern pattern = new Pattern( context.getNextPatternId(), 0, argsObjectType, null ); for ( int i = 0, length = args.size(); i < length; i++ ) { BaseDescr arg = args.get( i ); if ( arg instanceof LiteralDescr ) { arguments.add( ((LiteralDescr) arg).getValue() ); } else if ( arg instanceof VariableDescr ) { String var = ((VariableDescr) arg).getIdentifier(); Declaration declr = context.getDeclarationResolver().getDeclaration( query, var ); if ( declr != null ) { // declaration declrIndexes.add( i ); arguments.add( declr ); requiredDeclarations.add( declr ); } else { // unification variable declr = pattern.addDeclaration( var ); // this bit is different, notice its the ArrayElementReader that we wire up to, not the declaration. ArrayElementReader reader = new ArrayElementReader( arrayReader, varIndexes.size(), params[i].getExtractor().getExtractToClass() ); declr.setReadAccessor( reader ); varIndexes.add( i ); arguments.add( new Variable() ); } } } Declaration[] declrsArray = requiredDeclarations.toArray( new Declaration[requiredDeclarations.size()] ); int[] declrIndexArray = new int[declrIndexes.size()]; for( int i = 0; i < declrsArray.length; i++ ) { declrIndexArray[i] = declrIndexes.get( i ); } int[] varIndexesArray = new int[varIndexes.size()]; for( int i = 0; i < varIndexesArray.length; i++ ) { varIndexesArray[i] = varIndexes.get( i ); } return new QueryElement( pattern, query.getName(), arguments.toArray( new Object[arguments.size()] ), declrsArray, declrIndexArray, varIndexesArray ); } }