Advertisement
msangel

ExecIterator

Jun 5th, 2014
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.10 KB | None | 0 0
  1. package net.sinistersky.j2ee.support;
  2.  
  3. import com.google.gson.JsonElement;
  4.  
  5. /**
  6.  * This iterator recursively iterate over JSON tree and evaluate appropriate expression part for each node.
  7.  * All nodes, that match to whole expression is accessible via iterator.
  8.  * This class is a part of GsonPath library(<a href="https://github.com/msangel/JsonPath-Gson">https://github.com/msangel/JsonPath-Gson</a>)<br/>.
  9.  * License:  Apache License 2.0
  10.  * @author msangel &lt;h6.msangel@gmail.com&gt;
  11.  *
  12.  */
  13. final class ExecIterator extends PeekableIterator<JsonElement> {
  14.  
  15.     private final JsonPath2.Expression expression;
  16.     private final PeekableIterator<JsonElement> in;
  17.     private final int filterPosition;
  18.     private PeekableIterator<JsonElement> current;
  19.     private JsonElement next = null;
  20.     private boolean isNextTaken = false;
  21.  
  22.     ExecIterator(JsonPath2.Expression expression, PeekableIterator<JsonElement> in, int filterPosition) {
  23.         this.expression = expression;
  24.         this.in = in;
  25.         this.filterPosition = filterPosition;
  26.     }
  27.  
  28.     public boolean hasNext() {
  29.         if(current!=null){ // if have current iterator - delegate checking to it
  30.             return current.hasNext();
  31.         }
  32.         if(!isNextTaken){
  33.             this.next = takeNext();
  34.             isNextTaken = true;
  35.         }
  36.         return !(next==null);
  37.     }
  38.    
  39.  
  40.     public JsonElement next(){
  41.         if(isNextTaken){
  42.             isNextTaken = false;
  43.             return next;
  44.         } else {
  45.             return takeNext();
  46.         }
  47.     }
  48.  
  49.     /**
  50.      * This function return only next or null. This function should not change {@link #isNextTaken} and {@link #next} fields.
  51.      * @return next item in iteration.
  52.      */
  53.     private JsonElement takeNext(){
  54.         if(current!=null){ // if here - current has least one item
  55.             if(current.hasNext()){
  56.                 JsonElement next = current.next();
  57.                 if(!current.hasNext()){
  58.                     current = null;
  59.                 }
  60.                 return next;
  61.             } else {
  62.                 current = null;
  63.             }
  64.         }
  65.        
  66.         if(filterPosition>=this.expression.nodes.size()){
  67.             if(in.hasNext()){
  68.                 return in.next();
  69.             } else {
  70.                 return null;
  71.             }
  72.         }
  73.        
  74.        
  75.         PathNode pathNode = expression.getNodes().get(filterPosition);
  76.        
  77.         while (in.hasNext()){
  78.             JsonElement next = in.next();
  79.             PeekableIterator<JsonElement> filtered = pathNode.filter(next); // current element children
  80.             if(filtered.hasNext()){
  81.                 // cases:
  82.                 // 1) no items - skip this case and trying to get item from next iteration  
  83.                 // 2) one item - return it
  84.                 // 3) few items - save 'current' iterator for accession other items in this iterator for the next time.
  85.                 ExecIterator iter = new ExecIterator(this.expression, filtered, filterPosition+1);
  86.                 if(iter.hasNext()){
  87.                     JsonElement returned = iter.next();
  88.                     if(iter.hasNext()){ // few items
  89.                         current = iter;
  90.                     }
  91.                     return returned;
  92.                 }
  93.             } // no items - else in.next() and once again till not get result or all list is ended
  94.             //  move this all to 'hasNext' for keeping logic correct
  95.         }
  96.         return null; // no items at all
  97.     }
  98.    
  99.     @Override
  100.     JsonElement peek() {
  101.         if(current!=null){
  102.             return current.peek();
  103.         }
  104.         if(isNextTaken){
  105.             return next;
  106.         } else {
  107.             this.next = takeNext();
  108.             return next;
  109.         }
  110.     }
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement