/** * 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.expr.nodset; import jlibs.xml.sax.dog.expr.Expression; import jlibs.xml.sax.dog.path.PositionalPredicate; import jlibs.xml.sax.dog.sniff.Event; /** * @author Santhosh Kumar T */ public class PositionTracker{ public int position; private PositionMatches positionMatchesHead; public PositionTracker(PositionalPredicate positionPredicate){ if(positionPredicate!=null){ PositionMatches positionMatches = positionMatchesHead = new PositionMatches(positionPredicate); while((positionPredicate = positionPredicate.next)!=null) positionMatches = positionMatches.next = new PositionMatches(positionPredicate); } } private PositionMatches getPositionMatches(Expression predicate){ PositionMatches positionMatches = positionMatchesHead; do{ if(positionMatches.predicate==predicate) return positionMatches; }while((positionMatches=positionMatches.next)!=null); return null; } void addPositionListener(PositionalEvaluation evaluation){ PositionMatches positionMatches = getPositionMatches(evaluation.expression.predicate); assert positionMatches.map.lastEntry().value==positionMatches.listeners; positionMatches.listeners.addListener(evaluation); } void removePositionListener(PositionalEvaluation evaluation){ PositionMatches positionMatches = getPositionMatches(evaluation.expression.predicate); PositionalListeners positionalListeners = positionMatches.map.get(evaluation.order); if(positionalListeners==null) evaluation.disposed = true; else positionalListeners.removeListener(evaluation); } private PositionalEvaluation lastListenerHead, lastListenerTail; void addLastLitener(PositionalEvaluation evaluation){ Expression predicate = evaluation.expression.predicate; if(predicate==null){ if(lastListenerTail==null) lastListenerHead = lastListenerTail = evaluation; else{ lastListenerTail.next = evaluation; evaluation.previous = lastListenerTail; lastListenerTail = evaluation; } }else{ PositionMatches matches = getPositionMatches(predicate); if(matches.lastListenerTail==null) matches.lastListenerHead = matches.lastListenerTail = evaluation; else{ matches.lastListenerTail.next = evaluation; evaluation.previous = matches.lastListenerTail; matches.lastListenerTail = evaluation; } } } void removeLastLitener(PositionalEvaluation evaluation){ PositionalEvaluation prev = evaluation.previous; PositionalEvaluation next = evaluation.next; Expression predicate = evaluation.expression.predicate; if(predicate==null){ if(prev!=null) prev.next = next; else lastListenerHead = next; if(next!=null) next.previous = prev; else lastListenerTail = prev; }else{ PositionMatches matches = getPositionMatches(predicate); if(prev!=null) prev.next = next; else matches.lastListenerHead = next; if(next!=null) next.previous = prev; else matches.lastListenerTail = prev; } } public void addEvaluation(Event event){ position++; if(positionMatchesHead!=null){ PositionMatches positionMatches = positionMatchesHead; do{ positionMatches.addEvaluation(event); }while((positionMatches=positionMatches.next)!=null); } } public void startEvaluation(){ if(positionMatchesHead!=null){ PositionMatches positionMatches = positionMatchesHead; do{ positionMatches.startEvaluation(); }while((positionMatches=positionMatches.next)!=null); } } public void expired(){ if(lastListenerHead!=null){ Double last = (double)position; for(PositionalEvaluation lastEval=lastListenerHead; lastEval!=null; lastEval=lastEval.next) lastEval.setResult(last); lastListenerHead = lastListenerTail = null; } if(positionMatchesHead!=null){ PositionMatches positionMatches = positionMatchesHead; do{ positionMatches.expired(); }while((positionMatches=positionMatches.next)!=null); } } }