/** * Copyright 2015 Santhosh Kumar Tekuri * * The JLibs authors license this file to you 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 jlibs.xml.sax.dog.path; import jlibs.xml.sax.dog.DataType; import jlibs.xml.sax.dog.Scope; import jlibs.xml.sax.dog.expr.Expression; import jlibs.xml.sax.dog.expr.func.FunctionCall; import jlibs.xml.sax.dog.expr.func.Functions; import jlibs.xml.sax.dog.expr.nodset.ExactPosition; import jlibs.xml.sax.dog.expr.nodset.Positional; /** * @author Santhosh Kumar T */ public class PredicateSet{ protected Expression predicate; public boolean hasPosition; public PositionalPredicate headPositionalPredicate, tailPositionalPredicate; public int position, last; private int _position, _last; protected boolean hasPosition(Expression expr){ if(expr instanceof Positional){ Positional positional = (Positional)expr; positional.predicate = predicate; if(positional.position) _position++; else _last++; return true; }else if(expr instanceof FunctionCall){ FunctionCall functionCall = (FunctionCall)expr; boolean hasPosition = false; for(Expression member: functionCall.members){ if(hasPosition(member)) hasPosition = true; } return hasPosition; } return false; } public boolean impossible; public void setPredicate(Expression predicate){ assert predicate.resultType== DataType.BOOLEAN : "predicate must of boolean type"; if(impossible) return; // [exact-position(number)][exact-position(1)] can be simplified to [exact-position(number)] // [exact-position(number)][exact-position(numberNotEqualToOne)] can be simplified to <impossible> if(this.predicate instanceof ExactPosition && predicate instanceof ExactPosition){ ExactPosition exactPosition = (ExactPosition)predicate; if(exactPosition.pos!=1) impossible = true; return; } if(predicate.scope()== Scope.GLOBAL){ if(predicate.getResult()==Boolean.FALSE) impossible = true; return; } if(this.predicate!=null && this.predicate.scope()==Scope.DOCUMENT){ FunctionCall and = new FunctionCall(Functions.AND); and.addValidMember(this.predicate, 0); and.addValidMember(predicate, 1); predicate = and; this.predicate = null; } _position = _last = 0; if(hasPosition(predicate)){ hasPosition = true; if(this.predicate!=null){ PositionalPredicate positionalPredicate = new PositionalPredicate(this.predicate, _position, _last); if(tailPositionalPredicate!=null){ tailPositionalPredicate.next = positionalPredicate; tailPositionalPredicate = positionalPredicate; }else headPositionalPredicate = tailPositionalPredicate = positionalPredicate; this.predicate = null; }else{ position = _position; last = _last; } } if(this.predicate==null) this.predicate = predicate; else{ FunctionCall and = new FunctionCall(Functions.AND); and.addValidMember(this.predicate, 0); and.addValidMember(predicate, 1); this.predicate = and; } } public Expression getPredicate(){ return predicate; } }