/** * Copyright 2010 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * 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.verifier.visitor; import org.drools.lang.descr.AccumulateDescr; import org.drools.lang.descr.AndDescr; import org.drools.lang.descr.BaseDescr; import org.drools.lang.descr.CollectDescr; import org.drools.lang.descr.DeclarativeInvokerDescr; import org.drools.lang.descr.EntryPointDescr; import org.drools.lang.descr.FieldBindingDescr; import org.drools.lang.descr.FieldConstraintDescr; import org.drools.lang.descr.FromDescr; import org.drools.lang.descr.OrDescr; import org.drools.lang.descr.PatternDescr; import org.drools.lang.descr.PredicateDescr; import org.drools.verifier.components.Import; import org.drools.verifier.components.ObjectType; import org.drools.verifier.components.OperatorDescrType; import org.drools.verifier.components.Pattern; import org.drools.verifier.components.PatternOperatorDescr; import org.drools.verifier.components.Variable; import org.drools.verifier.components.VerifierAccumulateDescr; import org.drools.verifier.components.VerifierCollectDescr; import org.drools.verifier.components.VerifierComponentType; import org.drools.verifier.components.EntryPoint; import org.drools.verifier.components.VerifierFromDescr; import org.drools.verifier.components.PatternEval; import org.drools.verifier.components.VerifierRule; import org.drools.verifier.components.WorkingMemory; import org.drools.verifier.data.VerifierComponent; import org.drools.verifier.data.VerifierData; import org.drools.verifier.solver.Solvers; public class PatternDescrVisitor extends ConditionalElementDescrVisitor { private ObjectType objectType; private Pattern pattern; private WorkingMemory workingMemory = null; public PatternDescrVisitor(VerifierData data, VerifierRule rule, Solvers solvers) { super( data, solvers ); this.rule = rule; } public void visit(PatternDescr descr, VerifierComponent parent, int orderNumber) throws UnknownDescriptionException { visitPatternDescr( descr, parent, orderNumber ); } public void visit(PatternDescr descr, int orderNumber) throws UnknownDescriptionException { visitPatternDescr( descr, null, orderNumber ); } private Pattern visitPatternDescr(PatternDescr descr, VerifierComponent parent, int orderNumber) throws UnknownDescriptionException { objectType = data.getObjectTypeByFullName( descr.getObjectType() ); if ( objectType == null ) { Import objectImport = data.getImportByName( descr.getObjectType() ); if ( objectImport != null ) { objectType = ObjectTypeFactory.createObjectType( objectImport ); } else { objectType = ObjectTypeFactory.createObjectType( descr.getObjectType() ); } data.add( objectType ); } pattern = new Pattern( rule ); if ( parent != null ) { pattern.setParentPath( parent.getPath() ); pattern.setParentType( parent.getVerifierComponentType() ); } pattern.setObjectTypePath( objectType.getPath() ); pattern.setName( objectType.getName() ); pattern.setPatternNot( solvers.getRuleSolver().isChildNot() ); pattern.setPatternExists( solvers.getRuleSolver().isExists() ); pattern.setPatternForall( solvers.getRuleSolver().isForall() ); pattern.setOrderNumber( orderNumber ); if ( descr.getIdentifier() != null ) { Variable variable = new Variable( rule ); variable.setName( descr.getIdentifier() ); variable.setObjectTypeType( VerifierComponentType.OBJECT_TYPE.getType() ); variable.setObjectTypePath( objectType.getPath() ); variable.setObjectTypeType( descr.getObjectType() ); data.add( variable ); } // visit source. if ( descr.getSource() != null ) { visit( descr.getSource() ); } else { if ( workingMemory == null ) { workingMemory = new WorkingMemory(); data.add( workingMemory ); } pattern.setSourcePath( workingMemory.getPath() ); pattern.setSourceType( workingMemory.getVerifierComponentType() ); } solvers.startPatternSolver( pattern ); visit( descr.getConstraint() ); solvers.endPatternSolver(); data.add( pattern ); return pattern; } @Override protected VerifierComponent getParent() { return pattern; } @Override protected void visit(Object descr) throws UnknownDescriptionException { if ( descr instanceof AccumulateDescr ) { visitAccumulateDescr( (AccumulateDescr) descr ); } else if ( descr instanceof CollectDescr ) { visitCollectDescr( (CollectDescr) descr ); } else if ( descr instanceof EntryPointDescr ) { visitEntryPointDescr( (EntryPointDescr) descr ); } else if ( descr instanceof FromDescr ) { visitFromDescr( (FromDescr) descr ); } else if ( descr instanceof AndDescr ) { visitAndDescr( (AndDescr) descr ); } else if ( descr instanceof OrDescr ) { visitOrDescr( (OrDescr) descr ); } else if ( descr instanceof FieldConstraintDescr ) { visitFieldConstraintDescr( (FieldConstraintDescr) descr ); } else if ( descr instanceof FieldBindingDescr ) { visitFieldBindingDescr( (FieldBindingDescr) descr ); } else if ( descr instanceof PredicateDescr ) { visitPredicateDescr( (PredicateDescr) descr ); } else { throw new UnknownDescriptionException( (BaseDescr) descr ); } } /** * End leaf * * @param descr * @return */ private PatternEval visitPredicateDescr(PredicateDescr descr) { PatternEval predicate = new PatternEval( pattern ); predicate.setContent( descr.getContent().toString() ); predicate.setClassMethodName( descr.getClassMethodName() ); predicate.setOrderNumber( orderNumber.next() ); predicate.setParentPath( pattern.getPath() ); predicate.setParentType( pattern.getVerifierComponentType() ); data.add( predicate ); solvers.addPatternComponent( predicate ); return predicate; } /** * End * * @param descr */ private void visitFieldBindingDescr(FieldBindingDescr descr) { Variable variable = new Variable( rule ); variable.setName( descr.getIdentifier() ); variable.setOrderNumber( orderNumber.next() ); variable.setParentPath( rule.getPath() ); variable.setParentType( rule.getVerifierComponentType() ); variable.setObjectTypeType( VerifierComponentType.FIELD.getType() ); data.add( variable ); } private void visitFieldConstraintDescr(FieldConstraintDescr descr) throws UnknownDescriptionException { FieldConstraintDescrVisitor visitor = new FieldConstraintDescrVisitor( data, pattern, solvers, orderNumber.next() ); visitor.visitFieldConstraintDescr( descr ); } private void visitEntryPointDescr(EntryPointDescr descr) throws UnknownDescriptionException { // Check if already exists EntryPoint entryPoint = data.getEntryPointByEntryId( descr.getEntryId() ); if ( entryPoint == null ) { entryPoint = new EntryPoint(); entryPoint.setEntryPointName( descr.getEntryId() ); data.add( entryPoint ); } pattern.setSourcePath( entryPoint.getPath() ); pattern.setSourceType( entryPoint.getVerifierComponentType() ); } /** * End leaf * * @param descr * @return * @throws UnknownDescriptionException */ private VerifierFromDescr visitFromDescr(FromDescr descr) throws UnknownDescriptionException { VerifierFromDescr from = new VerifierFromDescr( pattern ); VerifierComponent ds = visit( descr.getDataSource() ); from.setDataSourcePath( ds.getPath() ); from.setDataSourceType( ds.getVerifierComponentType() ); from.setParentPath( rule.getPath() ); from.setParentType( rule.getVerifierComponentType() ); data.add( from ); return from; } private VerifierCollectDescr visitCollectDescr(CollectDescr descr) throws UnknownDescriptionException { VerifierCollectDescr collect = new VerifierCollectDescr( pattern ); collect.setClassMethodName( descr.getClassMethodName() ); PatternDescrVisitor visitor = new PatternDescrVisitor( data, rule, solvers ); visitor.visit( descr.getInputPattern(), collect, 0 ); collect.setParentPath( rule.getPath() ); collect.setParentType( rule.getVerifierComponentType() ); data.add( collect ); return collect; } private VerifierAccumulateDescr visitAccumulateDescr(AccumulateDescr descr) throws UnknownDescriptionException { VerifierAccumulateDescr accumulate = new VerifierAccumulateDescr( pattern ); PatternDescrVisitor visitor = new PatternDescrVisitor( data, rule, solvers ); Pattern parentPattern = visitor.visitPatternDescr( descr.getInputPattern(), null, 0 ); accumulate.setInitCode( descr.getInitCode() ); accumulate.setActionCode( descr.getActionCode() ); accumulate.setReverseCode( descr.getReverseCode() ); accumulate.setResultCode( descr.getResultCode() ); // XXX: Array seems to be always null. // accumulate.setDeclarations(descr.getDeclarations()); accumulate.setClassName( descr.getClassName() ); accumulate.setExternalFunction( descr.isExternalFunction() ); accumulate.setFunctionIdentifier( descr.getFunctionIdentifier() ); accumulate.setExpression( descr.getExpression() ); accumulate.setParentPath( parentPattern.getPath() ); accumulate.setParentType( parentPattern.getVerifierComponentType() ); data.add( accumulate ); return accumulate; } protected VerifierComponent visit(DeclarativeInvokerDescr descr) throws UnknownDescriptionException { DeclarativeInvokerDescrVisitor visitor = new DeclarativeInvokerDescrVisitor( data, rule ); return visitor.visit( descr ); } @Override protected void visitAndDescr(AndDescr descr) throws UnknownDescriptionException { PatternOperatorDescr operatorDescr = new PatternOperatorDescr( pattern, OperatorDescrType.AND ); operatorDescr.setOrderNumber( orderNumber.next() ); operatorDescr.setParentPath( getParent().getPath() ); operatorDescr.setParentType( getParent().getVerifierComponentType() ); data.add( operatorDescr ); solvers.startOperator( OperatorDescrType.AND ); visit( descr.getDescrs() ); solvers.endOperator(); } @Override protected void visitOrDescr(OrDescr descr) throws UnknownDescriptionException { PatternOperatorDescr operatorDescr = new PatternOperatorDescr( pattern, OperatorDescrType.OR ); operatorDescr.setOrderNumber( orderNumber.next() ); data.add( operatorDescr ); solvers.startOperator( OperatorDescrType.OR ); visit( descr.getDescrs() ); solvers.endOperator(); } }