001package ca.uhn.hl7v2.util;
002
003import java.io.InputStream;
004import java.io.Reader;
005import java.util.Iterator;
006
007import ca.uhn.hl7v2.HL7Exception;
008import ca.uhn.hl7v2.model.Message;
009import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
010import ca.uhn.hl7v2.parser.PipeParser;
011import ca.uhn.hl7v2.util.Hl7InputStreamMessageStringIterator.ParseFailureError;
012import 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 */
035public 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}