Coverage Report - ca.uhn.hl7v2.util.ReadOnlyMessageIterator
 
Classes in this File Line Coverage Branch Coverage Complexity
ReadOnlyMessageIterator
86%
25/29
90%
9/10
2
ReadOnlyMessageIterator$1
50%
2/4
50%
1/2
2
 
 1  
 /**
 2  
  * The contents of this file are subject to the Mozilla Public License Version 1.1
 3  
  * (the "License"); you may not use this file except in compliance with the License.
 4  
  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
 5  
  * Software distributed under the License is distributed on an "AS IS" basis,
 6  
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
 7  
  * specific language governing rights and limitations under the License.
 8  
  *
 9  
  * The Original Code is "ReadOnlyMessageIterator.java".  Description:
 10  
  * "Iterator though existing Stuctures in a message.   "
 11  
  *
 12  
  * The Initial Developer of the Original Code is University Health Network. Copyright (C)
 13  
  * 2005.  All Rights Reserved.
 14  
  *
 15  
  * Contributor(s): ______________________________________.
 16  
  *
 17  
  * Alternatively, the contents of this file may be used under the terms of the
 18  
  * GNU General Public License (the "GPL"), in which case the provisions of the GPL are
 19  
  * applicable instead of those above.  If you wish to allow use of your version of this
 20  
  * file only under the terms of the GPL and not to allow others to use your version
 21  
  * of this file under the MPL, indicate your decision by deleting  the provisions above
 22  
  * and replace  them with the notice and other provisions required by the GPL License.
 23  
  * If you do not delete the provisions above, a recipient may use your version of
 24  
  * this file under either the MPL or the GPL.
 25  
  *
 26  
  */
 27  
 package ca.uhn.hl7v2.util;
 28  
 
 29  
 import java.util.ArrayList;
 30  
 import java.util.Iterator;
 31  
 import java.util.List;
 32  
 import java.util.NoSuchElementException;
 33  
 
 34  
 import ca.uhn.hl7v2.HL7Exception;
 35  
 import ca.uhn.hl7v2.model.Group;
 36  
 import ca.uhn.hl7v2.model.Segment;
 37  
 import ca.uhn.hl7v2.model.Structure;
 38  
 
 39  
 /**
 40  
  * Iterator though existing Stuctures in a message.  No new repetitions or optional 
 41  
  * structures are created during iteration (in contrast to MessageIterator).  
 42  
  * 
 43  
  * Note that some structures are created during parsing, so the iteration may include 
 44  
  * structures which were not present in the original encoded message.  If these are 
 45  
  * not desired they can be skipped using a FilterIterator.  In fact to obtain an  
 46  
  * iterator only over populated segments (not groups or empty segments) use the factory 
 47  
  * method in this class.  
 48  
  *  
 49  
  * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
 50  
  * @version $Revision: 1.1 $ updated on $Date: 2007-02-19 02:24:27 $ by $Author: jamesagnew $
 51  
  */
 52  96
 public class ReadOnlyMessageIterator implements Iterator<Structure> {
 53  
 
 54  
     private List<Structure> myRemaining; //remaining nodes in reverse order (i.e. last is next)
 55  
     
 56  
     /**
 57  
      * @param theRoot root of depth first iteration, which starts with the first child  
 58  
      */
 59  5
     public ReadOnlyMessageIterator(Group theRoot) {
 60  5
         myRemaining = new ArrayList<Structure>(40);
 61  5
         addChildren(theRoot);
 62  5
     }
 63  
     
 64  
     /**
 65  
      * @param theRoot root of depth first iteration, which starts with the first child
 66  
      * @return an iterator that skips groups and empty segments, returning only populated 
 67  
      *      segments  
 68  
      */
 69  
     public static Iterator<Structure> createPopulatedSegmentIterator(Group theRoot) {
 70  1
         return createPopulatedStructureIterator(theRoot, Segment.class);       
 71  
     }
 72  
     
 73  
     /**
 74  
      * @param theRoot root of depth first iteration, which starts with the first child
 75  
      * @param c structure class to look for
 76  
      * @return an iterator that skips all structures that do not match the parameter
 77  
      */
 78  
     public static Iterator<Structure> createPopulatedStructureIterator(Group theRoot, Class<? extends Structure> c) {
 79  4
         return createPopulatedStructureIterator(theRoot, new StructurePredicate(c));       
 80  
     }    
 81  
 
 82  
     /**
 83  
      * @param theRoot root of depth first iteration, which starts with the first child
 84  
      * @param structureName structure name to look for
 85  
      * @return an iterator that skips all structures that do not match the parameter
 86  
      */
 87  
     public static Iterator<Structure> createPopulatedStructureIterator(Group theRoot, String structureName) {
 88  1
         return createPopulatedStructureIterator(theRoot, new StructureNamePredicate(structureName));
 89  
     }
 90  
     
 91  
     /**
 92  
      * @param theRoot root of depth first iteration, which starts with the first child
 93  
      * @param structureFilter filter class
 94  
      * @return iterator that skips all structures that the filter does not accept
 95  
      */
 96  
     public static Iterator<Structure> createPopulatedStructureIterator(Group theRoot, FilterIterator.Predicate<Structure> structureFilter) {
 97  5
         Iterator<Structure> allIterator = new ReadOnlyMessageIterator(theRoot);
 98  5
         Iterator<Structure> structureIterator = new FilterIterator<Structure>(allIterator, structureFilter);
 99  
         
 100  5
         FilterIterator.Predicate<Structure> populatedOnly = new FilterIterator.Predicate<Structure>() {
 101  
             public boolean evaluate(Structure obj) {
 102  
                 try {
 103  15
                     return !obj.isEmpty();
 104  0
                 } catch (HL7Exception e) {
 105  0
                     return false; // no exception expected
 106  
                 }
 107  
             }
 108  
         };
 109  5
         return new FilterIterator<Structure>(structureIterator, populatedOnly);         
 110  
     }
 111  
     
 112  
     private void addChildren(Group theParent) {
 113  50
         String[] names = theParent.getNames();
 114  227
         for (int i = names.length - 1; i >= 0; i--) {
 115  
             try {
 116  177
                 Structure[] reps = theParent.getAll(names[i]);
 117  279
                 for (int j = reps.length - 1; j >= 0; j--) {
 118  102
                     myRemaining.add(reps[j]);
 119  
                 }
 120  0
             } catch (HL7Exception e) {
 121  0
                 throw new Error("Internal error: an invalid child name was obtained from its parent.");
 122  177
             }
 123  
         }
 124  50
     }
 125  
 
 126  
     /** 
 127  
      * @see java.util.Iterator#hasNext()
 128  
      */
 129  
     public boolean hasNext() {
 130  196
         return !myRemaining.isEmpty();
 131  
     }
 132  
 
 133  
     /** 
 134  
      * @see java.util.Iterator#next()
 135  
      */
 136  
     public Structure next() {
 137  96
         if (!hasNext()) {
 138  0
             throw new NoSuchElementException("No more nodes in message");
 139  
         }
 140  
         
 141  96
         Structure next = myRemaining.remove(myRemaining.size() - 1);
 142  
         
 143  96
         if (next instanceof Group) {
 144  45
             addChildren((Group) next);
 145  
         }
 146  
         
 147  96
         return next;
 148  
     }
 149  
 
 150  
     /** 
 151  
      * Not supported.  
 152  
      */
 153  
     public void remove() {
 154  0
         throw new UnsupportedOperationException("Can't remove a node from a message");
 155  
     }
 156  
 
 157  
 }