Coverage Report - ca.uhn.hl7v2.util.SegmentFinder
 
Classes in this File Line Coverage Branch Coverage Complexity
SegmentFinder
93%
41/44
82%
23/28
3.375
 
 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 "SegmentFinder.java".  Description:
 10  
  * "A tool for getting segments by name within a message or part of a message."
 11  
  *
 12  
  * The Initial Developer of the Original Code is University Health Network. Copyright (C)
 13  
  * 2002.  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  
 
 28  
 package ca.uhn.hl7v2.util;
 29  
 
 30  
 import ca.uhn.hl7v2.model.*;
 31  
 import ca.uhn.hl7v2.HL7Exception;
 32  
 import java.util.regex.*;
 33  
 
 34  
 /**
 35  
  * A tool for getting segments by name within a message or part of a message.
 36  
  * @author Bryan Tripp
 37  
  */
 38  
 public class SegmentFinder extends MessageNavigator {
 39  
     
 40  
     /**
 41  
      * Creates a new instance of SegmentFinder.
 42  
      * @param root the scope of searches -- may be a whole message or only a branch
 43  
      */
 44  
     public SegmentFinder(Group root) {
 45  1770
         super(root);
 46  1770
     }
 47  
     
 48  
     /**
 49  
      * Returns the first segment with a name that matches the given pattern, in a depth-first search.  
 50  
      * Repeated searches are initiated from the location just AFTER where the last segment was found.
 51  
      * Call reset() is this is not desired.  Note: this means that the current location will not be found.
 52  
      * @param segmentName the name of the segment to find.  The wildcard * means any number 
 53  
      *      of arbitrary characters; the wildcard ? one arbitrary character
 54  
      *      (eg "P*" or "*ID" or "???" or "P??" would match on PID).
 55  
      * @param rep the repetition of the segment to return
 56  
      */
 57  
     public Segment findSegment(String namePattern, int rep) throws HL7Exception {
 58  186
         Structure s = null;
 59  
         do {
 60  186
             s = findStructure(namePattern, rep);
 61  186
         } while (!Segment.class.isAssignableFrom(s.getClass()));
 62  186
         return (Segment) s;
 63  
     }
 64  
     
 65  
     /**
 66  
      * As findSegment(), but will only return a group.
 67  
      */
 68  
     public Group findGroup(String namePattern, int rep) throws HL7Exception {
 69  88
         Structure s = null;
 70  
         do {
 71  88
             s = findStructure(namePattern, rep);
 72  88
         } while (!Group.class.isAssignableFrom(s.getClass()));
 73  88
         return (Group) s;
 74  
     }
 75  
     
 76  
     /**
 77  
      * Returns the first matching structure AFTER the current position
 78  
      */
 79  
     private Structure findStructure(String namePattern, int rep) throws HL7Exception {
 80  274
         Structure s = null;
 81  
         
 82  1932
         while (s == null) {
 83  1658
             String currentNameInParent = iterate(false, false);
 84  1658
             String currentName = getCurrentStructure(0).getName();
 85  1658
             if (matches(namePattern, currentName) || matches(namePattern, currentNameInParent)) {
 86  274
                 s = getCurrentStructure(rep);
 87  
             }
 88  1658
         }
 89  274
         return s;
 90  
     }
 91  
     
 92  
     /**
 93  
      * Returns the first segment with a name matching the given pattern that is a sibling of
 94  
      * the structure at the current location.  Other parts of the message are
 95  
      * not searched (in contrast to findSegment).
 96  
      * As a special case, if the pointer is at the root, the children of the root
 97  
      * are searched.
 98  
      * @param segmentName the name of the segment to get.  The wildcad * means any number 
 99  
      *      of arbitrary characters; the wildard ? one arbitrary character
 100  
      *      (eg "P*" or "*ID" or "???" or "P??" would match on PID).
 101  
      * @param rep the repetition of the segment to return
 102  
      */
 103  
     public Segment getSegment(String namePattern, int rep) throws HL7Exception {
 104  3121
         Structure s = getStructure(namePattern, rep);
 105  3119
         if (!Segment.class.isAssignableFrom(s.getClass())) {
 106  0
             throw new HL7Exception(s.getName() + " is not a segment");
 107  
         }
 108  3119
         return (Segment) s;
 109  
     }
 110  
     
 111  
     /**
 112  
      * As getSegment() but will only return a group.
 113  
      */
 114  
     public Group getGroup(String namePattern, int rep) throws HL7Exception {
 115  34
         Structure s = getStructure(namePattern, rep);
 116  34
         if (!Group.class.isAssignableFrom(s.getClass())) {
 117  0
             throw new HL7Exception(s.getName() + " is not a group");
 118  
         }
 119  34
         return (Group) s;
 120  
     }
 121  
     
 122  
     private Structure getStructure(String namePattern, int rep) throws HL7Exception {
 123  3155
         Structure s = null;
 124  
         
 125  3155
         if (getCurrentStructure(0).equals(this.getRoot()))
 126  2134
             drillDown(0);
 127  
         
 128  3155
         String[] names = getCurrentStructure(0).getParent().getNames();
 129  6530
         for (int i = 0; i < names.length && s == null; i++) {
 130  3375
             if (matches(namePattern, names[i])) {
 131  3153
                 toChild(i);
 132  3153
                 s = getCurrentStructure(rep);
 133  
             }
 134  
         }
 135  
         
 136  3155
         if (s == null)
 137  2
             throw new HL7Exception("Can't find " + namePattern + " as a direct child");
 138  
         
 139  3153
         return s;
 140  
     }
 141  
     
 142  
     /**
 143  
      * Tests whether the given name matches the given pattern.
 144  
      */
 145  
     /*private boolean matches(String pattern, String candidate) {
 146  
         boolean matches = false;
 147  
         boolean substring = false;
 148  
         if (pattern.substring(0, 1).equals("*")) {
 149  
             substring = true;
 150  
             pattern = pattern.substring(1);
 151  
         }
 152  
         
 153  
         if (substring && (candidate.indexOf(pattern) >= 0)) {
 154  
             matches = true;
 155  
         } else if (!substring && candidate.equals(pattern)) {
 156  
             matches = true;
 157  
         }
 158  
         return matches;
 159  
     }*/
 160  
     
 161  
     /**
 162  
      * Tests whether the given name matches the given pattern.
 163  
      */
 164  
     private boolean matches(String pattern, String candidate) {
 165  
         //shortcut ...
 166  6418
         if (pattern.equals(candidate)) {
 167  3406
             return true;
 168  
         }
 169  
         
 170  3012
         if (!Pattern.matches("[\\w\\*\\?]*", pattern)) 
 171  0
             throw new IllegalArgumentException("The pattern " + pattern + " is not valid.  Only [\\w\\*\\?]* allowed.");
 172  
         
 173  3012
         pattern = Pattern.compile("\\*").matcher(pattern).replaceAll(".*");
 174  3012
         pattern = Pattern.compile("\\?").matcher(pattern).replaceAll(".");
 175  
         
 176  3012
         return Pattern.matches(pattern, candidate);
 177  
     }
 178  
 }