001    package ca.uhn.hl7v2.util;
002    
003    import java.io.InputStream;
004    import java.io.Reader;
005    import java.util.Iterator;
006    
007    import ca.uhn.hl7v2.HL7Exception;
008    import ca.uhn.hl7v2.model.Message;
009    import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
010    import ca.uhn.hl7v2.parser.PipeParser;
011    import ca.uhn.hl7v2.util.Hl7InputStreamMessageStringIterator.ParseFailureError;
012    import ca.uhn.hl7v2.validation.impl.ValidationContextImpl;
013    
014    /**
015     * <p>
016     * Reads from an {@link InputStream} containing a stream of encoded HL7 messages
017     * and iterates over those messages. This class is geared towards reading from
018     * files, and tries to be very lenient about the format of the stream,
019     * specifically concerning control characters and line endings. It should be
020     * safe to provide a stream containing Windows or Unix line endings (which will
021     * be treated as segment delimiters). It is also safe to provide a stream containing
022     * MLLP control blocks before and after each message (although these will not be
023     * validated! Do not use this class to read MLLP messages from a socket stream!)
024     * </p>
025     * <p>
026     * The input stream could, for example, be a FileInputStream reading from a text
027     * file containing a number of HL7 messages in plain text format.
028     * </p>
029     * <p>
030     * Usage note: If an IOException occurs while reading from the stream or a
031     * message parsing exception occurs, it will be thrown as an unchecked
032     * {@link ParseFailureError}
033     * </p>
034     */
035    public class Hl7InputStreamMessageIterator implements Iterator<Message> {
036    
037            private PipeParser myParser;
038            private Hl7InputStreamMessageStringIterator myWrapped;
039    
040            /**
041             * Constructor
042             * 
043             * @param theInputStream
044             *            The input stream to read from
045             */
046            public Hl7InputStreamMessageIterator(InputStream theInputStream) {
047                    myWrapped = new Hl7InputStreamMessageStringIterator(theInputStream);
048                    init();
049            }
050    
051            /**
052             * Constructor
053             * 
054             * @param theReader
055             *            The reader to read from
056             */
057            public Hl7InputStreamMessageIterator(Reader theReader) {
058                    myWrapped = new Hl7InputStreamMessageStringIterator(theReader);
059                    init();
060            }
061    
062            /**
063             * {@inheritDoc}
064             */
065            public boolean hasNext() {
066                    return myWrapped.hasNext();
067            }
068    
069            private void init() {
070                    myParser = new PipeParser();
071                    myParser.setValidationContext(new ValidationContextImpl());
072            }
073    
074            /**
075             * {@inheritDoc}
076             */
077            public Message next() {
078                    String nextString = myWrapped.next();
079                    Message retVal;
080                    try {
081                            retVal = myParser.parse(nextString);
082                    } catch (EncodingNotSupportedException e) {
083                            throw new Hl7InputStreamMessageStringIterator.ParseFailureError("Failed to parse message", e);
084                    } catch (HL7Exception e) {
085                            throw new Hl7InputStreamMessageStringIterator.ParseFailureError("Failed to parse message", e);
086                    }
087                    return retVal;
088            }
089    
090            /**
091             * Unsupported method!
092             * 
093             * @throws UnsupportedOperationException
094             *             If called
095             */
096            public void remove() {
097                    throw new UnsupportedOperationException();
098            }
099    
100            /**
101             * If set to true, any lines beginning with a hash (#) will be ignored. This allows
102             * you to place comments in a file to be read if needed.
103             */
104            public void setIgnoreComments(boolean theIgnoreComments) {
105                    myWrapped.setIgnoreComments(theIgnoreComments);
106            }
107    
108    }