Ejemplo n.º 1
0
        /// <summary> Extracts selected fields from a message.
        ///
        /// </summary>
        /// <param name="theMessageText">an unparsed message from which to get fields
        /// </param>
        /// <param name="thePathSpecs">Terser-like paths to fields in the message.  See documentation
        /// for Terser.  These paths are identical except that they start with the segment
        /// name (search flags and group names are to be omitted as they are not relevant
        /// with unparsed ER7 messages).
        /// </param>
        /// <returns> field values corresponding to the given paths
        /// </returns>
        /// <throws>  HL7Exception </throws>
        public static System.String[] getFields(System.String theMessageText, System.String[] thePathSpecs)
        {
            NuGenDatumPath[] paths = new NuGenDatumPath[thePathSpecs.Length];
            for (int i = 0; i < thePathSpecs.Length; i++)
            {
                SupportClass.Tokenizer tok     = new SupportClass.Tokenizer(thePathSpecs[i], "-", false);
                System.String          segSpec = tok.NextToken();
                tok = new SupportClass.Tokenizer(segSpec, "()", false);
                System.String segName = tok.NextToken();
                if (segName.Length != 3)
                {
                    throw new NuGenHL7Exception("In field path, " + segName + " is not a valid segment name");
                }
                int segRep = 0;
                if (tok.HasMoreTokens())
                {
                    System.String rep = tok.NextToken();
                    try
                    {
                        segRep = System.Int32.Parse(rep);
                    }
                    catch (System.FormatException e)
                    {
                        throw new NuGenHL7Exception("In field path, segment rep" + rep + " is not valid", e);
                    }
                }

                int[] indices = Terser.getIndices(thePathSpecs[i]);
                paths[i] = new NuGenDatumPath();
                paths[i].add(segName).add(segRep);
                paths[i].add(indices[0]).add(indices[1]).add(indices[2]).add(indices[3]);
            }
            return(getFields(theMessageText, paths));
        }
Ejemplo n.º 2
0
        /// <summary> Sends a message to a responder system, receives the reply, and
        /// returns the reply as a Message object.  This method is thread-safe - multiple
        /// threads can share an Initiator and call this method.  Responses are returned to
        /// the calling thread on the basis of message ID.
        /// </summary>
        public virtual Message sendAndReceive(Message out_Renamed)
        {
            if (out_Renamed == null)
            {
                throw new NuGenHL7Exception("Can't encode null message", NuGenHL7Exception.REQUIRED_FIELD_MISSING);
            }

            //register message with response Receiver(s) (by message ID)
            Terser t = new Terser(out_Renamed);

            System.String       messID = t.get_Renamed("/MSH-10");
            NuGenMessageReceipt mr     = this.conn.reserveResponse(messID);

            //log and send message
            System.String outbound = conn.Parser.encode(out_Renamed);

            try
            {
                this.conn.SendWriter.writeMessage(outbound);
            }
            catch (System.IO.IOException e)
            {
                conn.close();
                throw e;
            }

            //wait for response
            bool    done      = false;
            Message response  = null;
            long    startTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;

            while (!done)
            {
                lock (mr)
                {
                    try
                    {
                        System.Threading.Monitor.Wait(mr, TimeSpan.FromMilliseconds(500));                         //if it comes, notifyAll() will be called
                    }
                    catch (System.Threading.ThreadInterruptedException)
                    {
                    }

                    if (mr.Message != null)
                    {
                        //get message from receipt
                        System.String inbound = mr.Message;

                        //parse message
                        response = conn.Parser.parse(inbound);
                        done     = true;
                    }

                    //if ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 > startTime + timeoutMillis)
                    //throw new HL7Exception("Timeout waiting for response to message with control ID '" + messID);
                }
            }

            return(response);
        }
Ejemplo n.º 3
0
        /// <seealso cref="Genetibase.NuGenHL7.protocol.Initiator.sendAndReceive(Genetibase.NuGenHL7.model.Message)">
        /// </seealso>
        public virtual Message sendAndReceive(Message theMessage)
        {
            Terser t = new Terser(theMessage);

            System.String appAckNeeded = t.get_Renamed("/MSH-16");
            System.String msgId        = t.get_Renamed("/MSH-10");

            System.String messageText = Parser.encode(theMessage);
            System.Collections.IDictionary metadata    = getMetadata(theMessage);
            NuGenTransportable             out_Renamed = new NuGenTransportableImpl(messageText, metadata);

            if (needAck(appAckNeeded))
            {
                myProcessor.reserve(msgId, ReceiveTimeout);
            }

            myProcessor.send(out_Renamed, MaxRetries, RetryInterval);

            Message in_Renamed = null;

            if (needAck(appAckNeeded))
            {
                NuGenTransportable received = myProcessor.receive(msgId, ReceiveTimeout);
                if (received != null && received.Message != null)
                {
                    in_Renamed = Parser.parse(received.Message);
                }
            }

            return(in_Renamed);
        }
Ejemplo n.º 4
0
            public virtual void  Run()
            {
                try
                {
                    //get message ID
                    System.String ID          = MessageIDGenerator.Instance.NewID;
                    Message       out_Renamed = parser.parse(outText);
                    Terser        tOut        = new Terser(out_Renamed);
                    tOut.set_Renamed("/MSH-10", ID);

                    //send, get response
                    Message in_Renamed = initiator.sendAndReceive(out_Renamed);

                    //get ACK ID
                    Terser        tIn   = new Terser(in_Renamed);
                    System.String ackID = tIn.get_Renamed("/MSA-2");
                    if (ID.Equals(ackID))
                    {
                        System.Console.Out.WriteLine("OK - ack ID matches");
                    }
                    else
                    {
                        throw new System.SystemException("Ack ID for message " + ID + " is " + ackID);
                    }
                }
                catch (System.Exception e)
                {
                    SupportClass.WriteStackTrace(e, Console.Error);
                }
            }
		/// <param name="message">a parsed message to validate (note that MSH-9-1 and MSH-9-2 must be valued)
		/// </param>
		/// <returns> true if the message is OK
		/// </returns>
		/// <throws>  HL7Exception if there is at least one error and this validator is set to fail on errors </throws>
		public virtual bool validate(Message message)
		{
			Terser t = new Terser(message);
			NuGenMessageRule[] rules = myContext.getMessageRules(message.Version, t.get_Renamed("MSH-9-1"), t.get_Renamed("MSH-9-2"));
			
			NuGenValidationException toThrow = null;
			bool result = true;
			for (int i = 0; i < rules.Length; i++)
			{
				NuGenValidationException[] ex = rules[i].test(message);
				for (int j = 0; j < ex.Length; j++)
				{
					result = false;
					if (failOnError && toThrow == null)
					{
						toThrow = ex[j];
					}
				}
			}
			
			if (toThrow != null)
			{
				throw new NuGenHL7Exception("Invalid message", toThrow);
			}
			
			return result;
		}
Ejemplo n.º 6
0
			public virtual void  Run()
			{
				try
				{
					//get message ID
					System.String ID = MessageIDGenerator.Instance.NewID;
					Message out_Renamed = parser.parse(outText);
					Terser tOut = new Terser(out_Renamed);
					tOut.set_Renamed("/MSH-10", ID);
					
					//send, get response
					Message in_Renamed = initiator.sendAndReceive(out_Renamed);
					
					//get ACK ID
					Terser tIn = new Terser(in_Renamed);
					System.String ackID = tIn.get_Renamed("/MSA-2");
					if (ID.Equals(ackID))
					{
						System.Console.Out.WriteLine("OK - ack ID matches");
					}
					else
					{
						throw new System.SystemException("Ack ID for message " + ID + " is " + ackID);
					}
				}
				catch (System.Exception e)
				{
					SupportClass.WriteStackTrace(e, Console.Error);
				}
			}
Ejemplo n.º 7
0
        /// <param name="message">a parsed message to validate (note that MSH-9-1 and MSH-9-2 must be valued)
        /// </param>
        /// <returns> true if the message is OK
        /// </returns>
        /// <throws>  HL7Exception if there is at least one error and this validator is set to fail on errors </throws>
        public virtual bool validate(Message message)
        {
            Terser t = new Terser(message);

            NuGenMessageRule[] rules = myContext.getMessageRules(message.Version, t.get_Renamed("MSH-9-1"), t.get_Renamed("MSH-9-2"));

            NuGenValidationException toThrow = null;
            bool result = true;

            for (int i = 0; i < rules.Length; i++)
            {
                NuGenValidationException[] ex = rules[i].test(message);
                for (int j = 0; j < ex.Length; j++)
                {
                    result = false;
                    if (failOnError && toThrow == null)
                    {
                        toThrow = ex[j];
                    }
                }
            }

            if (toThrow != null)
            {
                throw new NuGenHL7Exception("Invalid message", toThrow);
            }

            return(result);
        }
Ejemplo n.º 8
0
        /// <summary> Fills in the details of an Application Reject message, including response and
        /// error codes, and a text error message.  This is the method to override if you want
        /// to respond differently.
        /// </summary>
        public virtual void  fillDetails(Message ack)
        {
            try
            {
                //populate MSA and ERR with generic error ...
                Segment msa = (Segment)ack.get_Renamed("MSA");
                Terser.set_Renamed(msa, 1, 0, 1, 1, "AR");
                Terser.set_Renamed(msa, 3, 0, 1, 1, "No appropriate destination could be found to which this message could be routed.");
                //this is max length

                //populate ERR segment if it exists (may not depending on version)
                Structure s = ack.get_Renamed("ERR");
                if (s != null)
                {
                    Segment err = (Segment)s;
                    Terser.set_Renamed(err, 1, 0, 4, 1, "207");
                    Terser.set_Renamed(err, 1, 0, 4, 2, "Application Internal Error");
                    Terser.set_Renamed(err, 1, 0, 4, 3, "HL70357");
                }
            }
            catch (System.Exception e)
            {
                throw new NuGenApplicationException("Error trying to create Application Reject message: " + e.Message);
            }
        }
        private System.String[] getDeclaredProfileIDs(Message theMessage)
        {
            Terser t      = new Terser(theMessage);
            bool   noMore = false;
            int    c      = 0;

            System.Collections.ArrayList declaredProfiles = new System.Collections.ArrayList(8);
            while (!noMore)
            {
                System.String path  = "MSH-21(" + c++ + ")";
                System.String idRep = t.get_Renamed(path);
                //FIXME fails if empty rep precedes full rep ... should add getAll() to Terser and use that
                if (idRep == null || idRep.Equals(""))
                {
                    noMore = true;
                }
                else
                {
                    declaredProfiles.Add(idRep);
                }
            }

            String[] retVal = new String[declaredProfiles.Count];
            declaredProfiles.CopyTo(retVal);

            return(retVal);
        }
Ejemplo n.º 10
0
        /// <summary> Formats a Message object into an HL7 message string using this parser's
        /// default encoding ("VB").
        /// </summary>
        /// <throws>  HL7Exception if the data fields in the message do not permit encoding </throws>
        /// <summary>      (e.g. required fields are null)
        /// </summary>
        protected internal override System.String doEncode(Message source)
        {
            //get encoding characters ...
            Segment msh = (Segment)source.get_Renamed("MSH");

            System.String fieldSepString = Terser.get_Renamed(msh, 1, 0, 1, 1);

            if (fieldSepString == null)
            {
                throw new NuGenHL7Exception("Can't encode message: MSH-1 (field separator) is missing");
            }

            char fieldSep = '|';

            if (fieldSepString != null && fieldSepString.Length > 0)
            {
                fieldSep = fieldSepString[0];
            }

            System.String encCharString = Terser.get_Renamed(msh, 2, 0, 1, 1);

            if (encCharString == null)
            {
                throw new NuGenHL7Exception("Can't encode message: MSH-2 (encoding characters) is missing");
            }

            if (encCharString.Length != 4)
            {
                throw new NuGenHL7Exception("Encoding characters '" + encCharString + "' invalid -- must be 4 characters", NuGenHL7Exception.DATA_TYPE_ERROR);
            }
            NuGenEncodingCharacters en = new NuGenEncodingCharacters(fieldSep, encCharString);

            //pass down to group encoding method which will operate recursively on children ...
            return(encode((Group)source, en));
        }
		private static NuGenTransportable makeAcceptAck(NuGenTransportable theMessage, System.String theAckCode, int theErrorCode, System.String theDescription)
		{
			
			Segment header = ourParser.getCriticalResponseData(theMessage.Message);
			Message out_Renamed;
			try
			{
				out_Renamed = DefaultApplication.makeACK(header);
			}
			catch (System.IO.IOException e)
			{
				throw new NuGenHL7Exception(e);
			}
			
			Terser t = new Terser(out_Renamed);
			t.set_Renamed("/MSA-1", theAckCode);
			
			//TODO: when 2.5 is available, use 2.5 fields for remaining problems 
			if (theErrorCode != NuGenHL7Exception.MESSAGE_ACCEPTED)
			{
				t.set_Renamed("/MSA-3", theDescription.Substring(0, (System.Math.Min(80, theDescription.Length)) - (0)));
				t.set_Renamed("/ERR-1-4-1", System.Convert.ToString(theErrorCode));
				t.set_Renamed("/ERR-1-4-3", "HL70357");
			}
			
			System.String originalEncoding = ourParser.getEncoding(theMessage.Message);
			System.String ackText = ourParser.encode(out_Renamed, originalEncoding);
			return new NuGenTransportableImpl(ackText);
		}
Ejemplo n.º 12
0
        private static NuGenTransportable makeAcceptAck(NuGenTransportable theMessage, System.String theAckCode, int theErrorCode, System.String theDescription)
        {
            Segment header = ourParser.getCriticalResponseData(theMessage.Message);
            Message out_Renamed;

            try
            {
                out_Renamed = DefaultApplication.makeACK(header);
            }
            catch (System.IO.IOException e)
            {
                throw new NuGenHL7Exception(e);
            }

            Terser t = new Terser(out_Renamed);

            t.set_Renamed("/MSA-1", theAckCode);

            //TODO: when 2.5 is available, use 2.5 fields for remaining problems
            if (theErrorCode != NuGenHL7Exception.MESSAGE_ACCEPTED)
            {
                t.set_Renamed("/MSA-3", theDescription.Substring(0, (System.Math.Min(80, theDescription.Length)) - (0)));
                t.set_Renamed("/ERR-1-4-1", System.Convert.ToString(theErrorCode));
                t.set_Renamed("/ERR-1-4-3", "HL70357");
            }

            System.String originalEncoding = ourParser.getEncoding(theMessage.Message);
            System.String ackText          = ourParser.encode(out_Renamed, originalEncoding);
            return(new NuGenTransportableImpl(ackText));
        }
Ejemplo n.º 13
0
        /// <summary> Returns the Applications that has been registered to handle
        /// messages of the type and trigger event of the given message, or null if
        /// there are none.
        /// </summary>
        private NuGenApplication getMatchingApplication(Message message)
        {
            Terser t = new Terser(message);

            System.String messageType  = t.get_Renamed("/MSH-9-1");
            System.String triggerEvent = t.get_Renamed("/MSH-9-2");
            return(this.getMatchingApplication(messageType, triggerEvent));
        }
Ejemplo n.º 14
0
        /// <summary> <p>Returns a minimal amount of data from a message string, including only the
        /// data needed to send a response to the remote system.  This includes the
        /// following fields:
        /// <ul><li>field separator</li>
        /// <li>encoding characters</li>
        /// <li>processing ID</li>
        /// <li>message control ID</li></ul>
        /// This method is intended for use when there is an error parsing a message,
        /// (so the Message object is unavailable) but an error message must be sent
        /// back to the remote system including some of the information in the inbound
        /// message.  This method parses only that required information, hopefully
        /// avoiding the condition that caused the original error.  The other
        /// fields in the returned MSH segment are empty.</p>
        /// </summary>
        public override Segment getCriticalResponseData(System.String message)
        {
            //try to get MSH segment
            int locStartMSH = message.IndexOf("MSH");

            if (locStartMSH < 0)
            {
                throw new NuGenHL7Exception("Couldn't find MSH segment in message: " + message, NuGenHL7Exception.SEGMENT_SEQUENCE_ERROR);
            }
            int locEndMSH = message.IndexOf('\r', locStartMSH + 1);

            if (locEndMSH < 0)
            {
                locEndMSH = message.Length;
            }
            System.String mshString = message.Substring(locStartMSH, (locEndMSH) - (locStartMSH));

            //find out what the field separator is
            char fieldSep = mshString[3];

            //get field array
            System.String[] fields = split(mshString, System.Convert.ToString(fieldSep));

            Segment msh = null;

            try
            {
                //parse required fields
                System.String   encChars      = fields[1];
                char            compSep       = encChars[0];
                System.String   messControlID = fields[9];
                System.String[] procIDComps   = split(fields[10], System.Convert.ToString(compSep));

                //fill MSH segment
                System.String version = "2.4";                 //default
                try
                {
                    version = this.getVersion(message);
                }
                catch (System.Exception)
                {
                    /* use the default */
                }

                msh = NuGenParser.makeControlMSH(version, Factory);
                Terser.set_Renamed(msh, 1, 0, 1, 1, System.Convert.ToString(fieldSep));
                Terser.set_Renamed(msh, 2, 0, 1, 1, encChars);
                Terser.set_Renamed(msh, 10, 0, 1, 1, messControlID);
                Terser.set_Renamed(msh, 11, 0, 1, 1, procIDComps[0]);
                Terser.set_Renamed(msh, 12, 0, 1, 1, version);
            }
            catch (System.Exception e)
            {
                throw new NuGenHL7Exception("Can't parse critical fields from MSH segment (" + e.GetType().FullName + ": " + e.Message + "): " + mshString, NuGenHL7Exception.REQUIRED_FIELD_MISSING, e);
            }

            return(msh);
        }
Ejemplo n.º 15
0
        /// <summary> Logs the given exception and creates an error message to send to the
        /// remote system.
        ///
        /// </summary>
        /// <param name="encoding">The encoding for the error message. If <code>null</code>, uses default encoding
        /// </param>
        public static System.String logAndMakeErrorMessage(System.Exception e, Segment inHeader, Parser p, System.String encoding)
        {
            // create error message ...
            System.String errorMessage = null;
            try
            {
                Message out_Renamed = NuGenDefaultApplication.makeACK(inHeader);
                Terser  t           = new Terser(out_Renamed);

                //copy required data from incoming message ...
                try
                {
                    t.set_Renamed("/MSH-10", MessageIDGenerator.Instance.NewID);
                }
                catch (System.IO.IOException ioe)
                {
                    throw new NuGenHL7Exception("Problem creating error message ID: " + ioe.Message);
                }

                //populate MSA ...
                t.set_Renamed("/MSA-1", "AE");                 //should this come from HL7Exception constructor?
                t.set_Renamed("/MSA-2", Terser.get_Renamed(inHeader, 10, 0, 1, 1));
                System.String excepMessage = e.Message;
                if (excepMessage != null)
                {
                    t.set_Renamed("/MSA-3", excepMessage.Substring(0, (System.Math.Min(80, excepMessage.Length)) - (0)));
                }

                /* Some earlier ACKs don't have ERRs, but I think we'll change this within HAPI
                 * so that there is a single ACK for each version (with an ERR). */
                //see if it's an HL7Exception (so we can get specific information) ...
                if (e.GetType().Equals(typeof(NuGenHL7Exception)))
                {
                    Segment err = (Segment)out_Renamed.get_Renamed("ERR");
                    ((NuGenHL7Exception)e).populate(err);
                }
                else
                {
                    t.set_Renamed("/ERR-1-4-1", "207");
                    t.set_Renamed("/ERR-1-4-2", "Application Internal Error");
                    t.set_Renamed("/ERR-1-4-3", "HL70357");
                }

                if (encoding != null)
                {
                    errorMessage = p.encode(out_Renamed, encoding);
                }
                else
                {
                    errorMessage = p.encode(out_Renamed);
                }
            }
            catch (System.IO.IOException ioe)
            {
                throw new NuGenHL7Exception("IOException creating error response message: " + ioe.Message, NuGenHL7Exception.APPLICATION_INTERNAL_ERROR);
            }
            return(errorMessage);
        }
		/// <param name="theMessage">a message from which to extract fields
		/// </param>
		/// <param name="theTerserPaths">a list of paths to desired fields, in the 
		/// form required by <code>Terser</code>.  
		/// </param>
		/// <returns> a Map from Terser paths to field values 
		/// </returns>
		public static System.Collections.IDictionary getFields(Message theMessage, System.Collections.IList theTerserPaths)
		{
			System.Collections.IDictionary fields = new System.Collections.Hashtable();
			Terser terser = new Terser(theMessage);
			for (int i = 0; i < theTerserPaths.Count; i++)
			{
				System.String path = (System.String) theTerserPaths[i];
				System.String fieldValue = terser.get_Renamed(path);
				fields[path] = fieldValue;
			}
			return fields;
		}
Ejemplo n.º 17
0
        /// <param name="theMessage">a message from which to extract fields
        /// </param>
        /// <param name="theTerserPaths">a list of paths to desired fields, in the
        /// form required by <code>Terser</code>.
        /// </param>
        /// <returns> a Map from Terser paths to field values
        /// </returns>
        public static System.Collections.IDictionary getFields(Message theMessage, System.Collections.IList theTerserPaths)
        {
            System.Collections.IDictionary fields = new System.Collections.Hashtable();
            Terser terser = new Terser(theMessage);

            for (int i = 0; i < theTerserPaths.Count; i++)
            {
                System.String path       = (System.String)theTerserPaths[i];
                System.String fieldValue = terser.get_Renamed(path);
                fields[path] = fieldValue;
            }
            return(fields);
        }
        /// <summary> Returns the first Application that has been bound to messages of this type.  </summary>
        private NuGenReceivingApplication findApplication(Message theMessage)
        {
            Terser         t       = new Terser(theMessage);
            AppRoutingData msgData = new NuGenAppRoutingDataImpl(t.get_Renamed("/MSH-9-1"), t.get_Renamed("/MSH-9-2"), t.get_Renamed("/MSH-11-1"), t.get_Renamed("/MSH-12"));

            NuGenReceivingApplication app = findDestination(msgData);

            //have to send back an application reject if no apps available to process
            if (app == null)
            {
                app = new NuGenAppWrapper(new DefaultApplication());
            }
            return(app);
        }
Ejemplo n.º 19
0
        /// <summary> Creates an ACK message with the minimum required information from an inbound message.
        /// Optional fields can be filled in afterwards, before the message is returned.  Pleaase
        /// note that MSH-10, the outbound message control ID, is also set using the class
        /// <code>Genetibase.NuGenHL7.util.MessageIDGenerator</code>.  Also note that the ACK messages returned
        /// is the same version as the version stated in the inbound MSH if there is a generic ACK for that
        /// version, otherwise a version 2.4 ACK is returned. MSA-1 is set to AA by default.
        ///
        /// </summary>
        /// <param name="inboundHeader">the MSH segment if the inbound message
        /// </param>
        /// <throws>  IOException if there is a problem reading or writing the message ID file </throws>
        /// <throws>  DataTypeException if there is a problem setting ACK values </throws>
        public static Message makeACK(Segment inboundHeader)
        {
            if (!inboundHeader.getName().Equals("MSH"))
            {
                throw new NuGenHL7Exception("Need an MSH segment to create a response ACK (got " + inboundHeader.getName() + ")");
            }

            //make ACK of correct version
            System.String version = null;
            try
            {
                version = Terser.get_Renamed(inboundHeader, 12, 0, 1, 1);
            }
            catch (NuGenHL7Exception)
            {
                /* proceed with null */
            }
            if (version == null)
            {
                version = "2.4";
            }

            System.String ackClassName = SourceGenerator.getVersionPackageName(version) + "message.ACK";

            Message out_Renamed = null;

            try
            {
                System.Type ackClass = System.Type.GetType(ackClassName);
                out_Renamed = (Message)System.Activator.CreateInstance(ackClass);
            }
            catch (System.Exception e)
            {
                throw new NuGenHL7Exception("Can't instantiate ACK of class " + ackClassName + ": " + e.GetType().FullName);
            }
            Terser terser = new Terser(out_Renamed);

            //populate outbound MSH using data from inbound message ...
            Segment outHeader = (Segment)out_Renamed.get_Renamed("MSH");

            fillResponseHeader(inboundHeader, outHeader);

            terser.set_Renamed("/MSH-9", "ACK");
            terser.set_Renamed("/MSH-12", version);
            terser.set_Renamed("/MSA-1", "AA");
            terser.set_Renamed("/MSA-2", Genetibase.NuGenHL7.util.NuGenTerser.get_Renamed(inboundHeader, 10, 0, 1, 1));

            return(out_Renamed);
        }
Ejemplo n.º 20
0
        private void  parse(SupportClass.Tokenizer tok, Message message, StructRef root, NuGenEncodingCharacters ec)
        {
            Terser t = new Terser(message);

            lock (root)
            {
                StructRef ref_Renamed = root.getSuccessor("MSH");

                int     field   = 0;
                Segment segment = null;
                int[]   fields  = new int[0];

                while (tok.HasMoreTokens())
                {
                    System.String token = tok.NextToken();
                    if (token[0] == ec.FieldSeparator)
                    {
                        field++;
                    }
                    else if (token[0] == ourSegmentSeparator)
                    {
                        field = 0;
                    }
                    else if (field == 0)
                    {
                        StructRef newref = drill(ref_Renamed, token);
                        if (newref == null)
                        {
                            segment = null;
                            fields  = new int[0];
                        }
                        else
                        {
                            ref_Renamed = newref;
                            segment     = t.getSegment(ref_Renamed.FullPath);
                            fields      = ref_Renamed.Fields;
                        }
                    }
                    else if (segment != null && System.Array.BinarySearch(fields, (System.Object)field) >= 0)
                    {
                        parse(token, segment, field, ec);
                    }
                }
                root.reset();
            }
        }
Ejemplo n.º 21
0
 /// <summary> Fills a field with values from an unparsed string representing the field.  </summary>
 /// <param name="destinationField">the field Type
 /// </param>
 /// <param name="data">the field string (including all components and subcomponents; not including field delimiters)
 /// </param>
 /// <param name="encodingCharacters">the encoding characters used in the message
 /// </param>
 private static void  parse(Type destinationField, System.String data, NuGenEncodingCharacters encodingCharacters)
 {
     System.String[] components = split(data, System.Convert.ToString(encodingCharacters.ComponentSeparator));
     for (int i = 0; i < components.Length; i++)
     {
         System.String[] subcomponents = split(components[i], System.Convert.ToString(encodingCharacters.SubcomponentSeparator));
         for (int j = 0; j < subcomponents.Length; j++)
         {
             System.String val = subcomponents[j];
             if (val != null)
             {
                 val = NuGenEscape.unescape(val, encodingCharacters);
             }
             Terser.getPrimitive(destinationField, i + 1, j + 1).Value = val;
         }
     }
 }
Ejemplo n.º 22
0
        private void  addProblemsToACK(Message ack, NuGenHL7Exception[] problems)
        {
            Terser t = new Terser(ack);

            if (problems.Length > 0)
            {
                t.set_Renamed("MSA-1", "AE");
                t.set_Renamed("MSA-3", "Errors were encountered while testing the message");
            }

            Segment err = (Segment)ack.get_Renamed("ERR");

            for (int i = 0; i < problems.Length; i++)
            {
                problems[i].populate(err);
            }
        }
Ejemplo n.º 23
0
        /// <summary> <p>Returns a minimal amount of data from a message string, including only the
        /// data needed to send a response to the remote system.  This includes the
        /// following fields:
        /// <ul><li>field separator</li>
        /// <li>encoding characters</li>
        /// <li>processing ID</li>
        /// <li>message control ID</li></ul>
        /// This method is intended for use when there is an error parsing a message,
        /// (so the Message object is unavailable) but an error message must be sent
        /// back to the remote system including some of the information in the inbound
        /// message.  This method parses only that required information, hopefully
        /// avoiding the condition that caused the original error.</p>
        /// </summary>
        public override Segment getCriticalResponseData(System.String message)
        {
            System.String version      = getVersion(message);
            Segment       criticalData = NuGenParser.makeControlMSH(version, Factory);

            Terser.set_Renamed(criticalData, 1, 0, 1, 1, parseLeaf(message, "MSH.1", 0));
            Terser.set_Renamed(criticalData, 2, 0, 1, 1, parseLeaf(message, "MSH.2", 0));
            Terser.set_Renamed(criticalData, 10, 0, 1, 1, parseLeaf(message, "MSH.10", 0));
            System.String procID = parseLeaf(message, "MSH.11", 0);
            if (procID == null || procID.Length == 0)
            {
                procID = parseLeaf(message, "PT.1", message.IndexOf("MSH.11"));
                //this field is a composite in later versions
            }
            Terser.set_Renamed(criticalData, 11, 0, 1, 1, procID);

            return(criticalData);
        }
Ejemplo n.º 24
0
 /// <summary> Encodes the given Type, using the given encoding characters.
 /// It is assumed that the Type represents a complete field rather than a component.
 /// </summary>
 public static System.String encode(Type source, NuGenEncodingCharacters encodingChars)
 {
     System.Text.StringBuilder field = new System.Text.StringBuilder();
     for (int i = 1; i <= Terser.numComponents(source); i++)
     {
         System.Text.StringBuilder comp = new System.Text.StringBuilder();
         for (int j = 1; j <= Terser.numSubComponents(source, i); j++)
         {
             Primitive p = Terser.getPrimitive(source, i, j);
             comp.Append(encodePrimitive(p, encodingChars));
             comp.Append(encodingChars.SubcomponentSeparator);
         }
         field.Append(stripExtraDelimiters(comp.ToString(), encodingChars.SubcomponentSeparator));
         field.Append(encodingChars.ComponentSeparator);
     }
     return(stripExtraDelimiters(field.ToString(), encodingChars.ComponentSeparator));
     //return encode(source, encodingChars, false);
 }
Ejemplo n.º 25
0
        private System.Collections.IDictionary getMetadata(Message theMessage)
        {
            System.Collections.IDictionary md = new System.Collections.Hashtable();
            Terser t = new Terser(theMessage);

            //snapshot so concurrent changes won't break our iteration

            Object[] fields = new Object[MetadataFields.Count];
            MetadataFields.CopyTo(fields, 0);

            for (int i = 0; i < fields.Length; i++)
            {
                System.String field = fields[i].ToString();
                System.String val   = t.get_Renamed(field);
                md[field] = val;
            }

            return(md);
        }
        /// <summary> Processes an incoming message string and returns the response message string.
        /// Message processing consists of parsing the message, finding an appropriate
        /// Application and processing the message with it, and encoding the response.
        /// Applications are chosen from among those registered using
        /// <code>bindApplication</code>.
        ///
        /// </summary>
        /// <returns> {text, charset}
        /// </returns>
        private System.String[] processMessage(System.String incomingMessageString, System.Collections.IDictionary theMetadata)
        {
            ;

            Message incomingMessageObject = null;

            System.String outgoingMessageString  = null;
            System.String outgoingMessageCharset = null;
            try
            {
                incomingMessageObject = myParser.parse(incomingMessageString);
            }
            catch (NuGenHL7Exception e)
            {
                outgoingMessageString = Responder.logAndMakeErrorMessage(e, myParser.getCriticalResponseData(incomingMessageString), myParser, myParser.getEncoding(incomingMessageString));
            }

            if (outgoingMessageString == null)
            {
                try
                {
                    //message validation (in terms of optionality, cardinality) would go here ***

                    NuGenReceivingApplication app = findApplication(incomingMessageObject);
                    theMetadata[RAW_MESSAGE_KEY] = incomingMessageString;
                    Message response = app.processMessage(incomingMessageObject, theMetadata);

                    //Here we explicitly use the same encoding as that of the inbound message - this is important with GenericParser, which might use a different encoding by default
                    outgoingMessageString = myParser.encode(response, myParser.getEncoding(incomingMessageString));

                    Terser t = new Terser(response);
                    outgoingMessageCharset = t.get_Renamed("MSH-18");
                }
                catch (System.Exception e)
                {
                    outgoingMessageString = Responder.logAndMakeErrorMessage(e, (Segment)incomingMessageObject.get_Renamed("MSH"), myParser, myParser.getEncoding(incomingMessageString));
                }
            }

            return(new System.String[] { outgoingMessageString, outgoingMessageCharset });
        }
Ejemplo n.º 27
0
        /// <summary> Tests table values for ID, IS, and CE types.  An empty list is returned for
        /// all other types or if the table name or number is missing.
        /// </summary>
        private NuGenHL7Exception[] testTypeAgainstTable(Genetibase.NuGenHL7.model.Type type, AbstractComponent profile, System.String profileID)
        {
            System.Collections.ArrayList exList = new System.Collections.ArrayList();
            if (profile.Table != null && type.Name.Equals("IS") || type.Name.Equals("ID"))
            {
                System.String codeSystem    = makeTableName(profile.Table);
                System.String value_Renamed = ((Primitive)type).Value;
                addTableTestResult(exList, profileID, codeSystem, value_Renamed);
            }
            else if (type.Name.Equals("CE"))
            {
                System.String value_Renamed = Terser.getPrimitive(type, 1, 1).Value;
                System.String codeSystem    = Terser.getPrimitive(type, 3, 1).Value;
                addTableTestResult(exList, profileID, codeSystem, value_Renamed);

                value_Renamed = Terser.getPrimitive(type, 4, 1).Value;
                codeSystem    = Terser.getPrimitive(type, 6, 1).Value;
                addTableTestResult(exList, profileID, codeSystem, value_Renamed);
            }
            return(this.toArray(exList));
        }
Ejemplo n.º 28
0
        /// <summary> Populates certain required fields in a response message header, using
        /// information from the corresponding inbound message.  The current time is
        /// used for the message time field, and <code>MessageIDGenerator</code> is
        /// used to create a unique message ID.  Version and message type fields are
        /// not populated.
        /// </summary>
        public static void  fillResponseHeader(Segment inbound, Segment outbound)
        {
            if (!inbound.getName().Equals("MSH") || !outbound.getName().Equals("MSH"))
            {
                throw new NuGenHL7Exception("Need MSH segments.  Got " + inbound.getName() + " and " + outbound.getName());
            }

            //get MSH data from incoming message ...
            System.String encChars = Terser.get_Renamed(inbound, 2, 0, 1, 1);
            System.String fieldSep = Terser.get_Renamed(inbound, 1, 0, 1, 1);
            System.String procID   = Terser.get_Renamed(inbound, 11, 0, 1, 1);

            //populate outbound MSH using data from inbound message ...
            Terser.set_Renamed(outbound, 2, 0, 1, 1, encChars);
            Terser.set_Renamed(outbound, 1, 0, 1, 1, fieldSep);
            System.Globalization.GregorianCalendar now = new System.Globalization.GregorianCalendar();
            SupportClass.CalendarManager.manager.SetDateTime(now, System.DateTime.Now);
            Terser.set_Renamed(outbound, 7, 0, 1, 1, CommonTS.toHl7TSFormat(now));
            Terser.set_Renamed(outbound, 10, 0, 1, 1, MessageIDGenerator.Instance.NewID);
            Terser.set_Renamed(outbound, 11, 0, 1, 1, procID);
        }
Ejemplo n.º 29
0
        /// <summary> Populates the given error segment with information from this Exception.</summary>
        public virtual void  populate(Segment errorSegment)
        {
            //make sure it's an ERR
            if (!errorSegment.getName().Equals("ERR"))
            {
                throw new NuGenHL7Exception("Can only populate an ERR segment with an exception -- got: " + errorSegment.GetType().FullName);
            }

            int rep = errorSegment.getField(1).Length;             //append after existing reps

            if (this.SegmentName != null)
            {
                Terser.set_Renamed(errorSegment, 1, rep, 1, 1, this.SegmentName);
            }

            if (this.SegmentRepetition >= 0)
            {
                Terser.set_Renamed(errorSegment, 1, rep, 2, 1, System.Convert.ToString(this.SegmentRepetition));
            }

            if (this.FieldPosition >= 0)
            {
                Terser.set_Renamed(errorSegment, 1, rep, 3, 1, System.Convert.ToString(this.FieldPosition));
            }

            Terser.set_Renamed(errorSegment, 1, rep, 4, 1, System.Convert.ToString(this.errCode));
            Terser.set_Renamed(errorSegment, 1, rep, 4, 3, "hl70357");
            Terser.set_Renamed(errorSegment, 1, rep, 4, 5, this.Message);

            //try to get error condition text
            try
            {
                System.String desc = NuGenTableRepository.Instance.getDescription(357, System.Convert.ToString(this.errCode));
                Terser.set_Renamed(errorSegment, 1, rep, 4, 2, desc);
            }
            catch (NuGenLookupException)
            {
            }
        }
Ejemplo n.º 30
0
        private void  parse(System.String field, Segment segment, int num, NuGenEncodingCharacters ec)
        {
            if (field != null)
            {
                int  rep          = 0;
                int  component    = 1;
                int  subcomponent = 1;
                Type type         = segment.getField(num, rep);

                System.String delim = System.Convert.ToString(new char[] { ec.RepetitionSeparator, ec.ComponentSeparator, ec.SubcomponentSeparator });
                for (SupportClass.Tokenizer tok = new SupportClass.Tokenizer(field, delim, true); tok.HasMoreTokens();)
                {
                    System.String token = tok.NextToken();
                    char          c     = token[0];
                    if (c == ec.RepetitionSeparator)
                    {
                        rep++;
                        component    = 1;
                        subcomponent = 1;
                        type         = segment.getField(num, rep);
                    }
                    else if (c == ec.ComponentSeparator)
                    {
                        component++;
                        subcomponent = 1;
                    }
                    else if (c == ec.SubcomponentSeparator)
                    {
                        subcomponent++;
                    }
                    else
                    {
                        Primitive p = Terser.getPrimitive(type, component, subcomponent);
                        p.Value = token;
                    }
                }
            }
        }
		/// <seealso cref="Validator.validate">
		/// </seealso>
		public virtual NuGenHL7Exception[] validate(Message message, StaticDef profile)
		{
			System.Collections.ArrayList exList = new System.Collections.ArrayList(20);
			Terser t = new Terser(message);
			
			//check msg type, event type, msg struct ID
			System.String msgType = t.get_Renamed("/MSH-9-1");
			if (!msgType.Equals(profile.MsgType))
			{
				NuGenHL7Exception e = new NuGenProfileNotFollowedException("Message type " + msgType + " doesn't match profile type of " + profile.MsgType);
				exList.Add(e);
			}
			
			System.String evType = t.get_Renamed("/MSH-9-2");
			if (!evType.Equals(profile.EventType) && !profile.EventType.ToUpper().Equals("ALL".ToUpper()))
			{
				NuGenHL7Exception e = new NuGenProfileNotFollowedException("Event type " + evType + " doesn't match profile type of " + profile.EventType);
				exList.Add(e);
			}
			
			System.String msgStruct = t.get_Renamed("/MSH-9-3");
			if (msgStruct == null || !msgStruct.Equals(profile.MsgStructID))
			{
				NuGenHL7Exception e = new NuGenProfileNotFollowedException("Message structure " + msgStruct + " doesn't match profile type of " + profile.MsgStructID);
				exList.Add(e);
			}
			
			System.Exception[] childExceptions;
			childExceptions = testGroup(message, profile, profile.Identifier);
			for (int i = 0; i < childExceptions.Length; i++)
			{
				exList.Add(childExceptions[i]);
			}
			
			return toArray(exList);
		}
Ejemplo n.º 32
0
        /// <seealso cref="Validator.validate">
        /// </seealso>
        public virtual NuGenHL7Exception[] validate(Message message, StaticDef profile)
        {
            System.Collections.ArrayList exList = new System.Collections.ArrayList(20);
            Terser t = new Terser(message);

            //check msg type, event type, msg struct ID
            System.String msgType = t.get_Renamed("/MSH-9-1");
            if (!msgType.Equals(profile.MsgType))
            {
                NuGenHL7Exception e = new NuGenProfileNotFollowedException("Message type " + msgType + " doesn't match profile type of " + profile.MsgType);
                exList.Add(e);
            }

            System.String evType = t.get_Renamed("/MSH-9-2");
            if (!evType.Equals(profile.EventType) && !profile.EventType.ToUpper().Equals("ALL".ToUpper()))
            {
                NuGenHL7Exception e = new NuGenProfileNotFollowedException("Event type " + evType + " doesn't match profile type of " + profile.EventType);
                exList.Add(e);
            }

            System.String msgStruct = t.get_Renamed("/MSH-9-3");
            if (msgStruct == null || !msgStruct.Equals(profile.MsgStructID))
            {
                NuGenHL7Exception e = new NuGenProfileNotFollowedException("Message structure " + msgStruct + " doesn't match profile type of " + profile.MsgStructID);
                exList.Add(e);
            }

            System.Exception[] childExceptions;
            childExceptions = testGroup(message, profile, profile.Identifier);
            for (int i = 0; i < childExceptions.Length; i++)
            {
                exList.Add(childExceptions[i]);
            }

            return(toArray(exList));
        }
		private System.String[] getDeclaredProfileIDs(Message theMessage)
		{
			Terser t = new Terser(theMessage);
			bool noMore = false;
			int c = 0;
			System.Collections.ArrayList declaredProfiles = new System.Collections.ArrayList(8);
			while (!noMore)
			{
				System.String path = "MSH-21(" + c++ + ")";
				System.String idRep = t.get_Renamed(path);
				//FIXME fails if empty rep precedes full rep ... should add getAll() to Terser and use that
				if (idRep == null || idRep.Equals(""))
				{
					noMore = true;
				}
				else
				{
					declaredProfiles.Add(idRep);
				}
			}

            String[] retVal = new String[declaredProfiles.Count];
            declaredProfiles.CopyTo(retVal);

            return retVal;
		}
		/// <summary> Creates an ACK message with the minimum required information from an inbound message.  
		/// Optional fields can be filled in afterwards, before the message is returned.  Pleaase   
		/// note that MSH-10, the outbound message control ID, is also set using the class 
		/// <code>Genetibase.NuGenHL7.util.MessageIDGenerator</code>.  Also note that the ACK messages returned
		/// is the same version as the version stated in the inbound MSH if there is a generic ACK for that
		/// version, otherwise a version 2.4 ACK is returned. MSA-1 is set to AA by default.  
		/// 
		/// </summary>
		/// <param name="inboundHeader">the MSH segment if the inbound message
		/// </param>
		/// <throws>  IOException if there is a problem reading or writing the message ID file </throws>
		/// <throws>  DataTypeException if there is a problem setting ACK values </throws>
		public static Message makeACK(Segment inboundHeader)
		{
			if (!inboundHeader.getName().Equals("MSH"))
				throw new NuGenHL7Exception("Need an MSH segment to create a response ACK (got " + inboundHeader.getName() + ")");
			
			//make ACK of correct version
			System.String version = null;
			try
			{
				version = Terser.get_Renamed(inboundHeader, 12, 0, 1, 1);
			}
			catch (NuGenHL7Exception)
			{
				/* proceed with null */
			}
			if (version == null)
				version = "2.4";
			
			System.String ackClassName = SourceGenerator.getVersionPackageName(version) + "message.ACK";
			
			Message out_Renamed = null;
			try
			{
				System.Type ackClass = System.Type.GetType(ackClassName);
				out_Renamed = (Message) System.Activator.CreateInstance(ackClass);
			}
			catch (System.Exception e)
			{
				throw new NuGenHL7Exception("Can't instantiate ACK of class " + ackClassName + ": " + e.GetType().FullName);
			}
			Terser terser = new Terser(out_Renamed);
			
			//populate outbound MSH using data from inbound message ...             
			Segment outHeader = (Segment) out_Renamed.get_Renamed("MSH");
			fillResponseHeader(inboundHeader, outHeader);
			
			terser.set_Renamed("/MSH-9", "ACK");
			terser.set_Renamed("/MSH-12", version);
			terser.set_Renamed("/MSA-1", "AA");
			terser.set_Renamed("/MSA-2", Genetibase.NuGenHL7.util.NuGenTerser.get_Renamed(inboundHeader, 10, 0, 1, 1));
			
			return out_Renamed;
		}
		/// <summary> Returns the first Application that has been bound to messages of this type.  </summary>
		private NuGenReceivingApplication findApplication(Message theMessage)
		{
			Terser t = new Terser(theMessage);
			AppRoutingData msgData = new NuGenAppRoutingDataImpl(t.get_Renamed("/MSH-9-1"), t.get_Renamed("/MSH-9-2"), t.get_Renamed("/MSH-11-1"), t.get_Renamed("/MSH-12"));
			
			NuGenReceivingApplication app = findDestination(msgData);
			
			//have to send back an application reject if no apps available to process
			if (app == null)
				app = new NuGenAppWrapper(new DefaultApplication());
			return app;
		}
		/// <summary> Processes an incoming message string and returns the response message string.
		/// Message processing consists of parsing the message, finding an appropriate
		/// Application and processing the message with it, and encoding the response.
		/// Applications are chosen from among those registered using
		/// <code>bindApplication</code>.  
		/// 
		/// </summary>
		/// <returns> {text, charset}
		/// </returns>
		private System.String[] processMessage(System.String incomingMessageString, System.Collections.IDictionary theMetadata)
		{;
			
			Message incomingMessageObject = null;
			System.String outgoingMessageString = null;
			System.String outgoingMessageCharset = null;
			try
			{
				incomingMessageObject = myParser.parse(incomingMessageString);
			}
			catch (NuGenHL7Exception e)
			{
				outgoingMessageString = Responder.logAndMakeErrorMessage(e, myParser.getCriticalResponseData(incomingMessageString), myParser, myParser.getEncoding(incomingMessageString));
			}
			
			if (outgoingMessageString == null)
			{
				try
				{				
					//message validation (in terms of optionality, cardinality) would go here ***
					
					NuGenReceivingApplication app = findApplication(incomingMessageObject);
					theMetadata[RAW_MESSAGE_KEY] = incomingMessageString;
					Message response = app.processMessage(incomingMessageObject, theMetadata);
					
					//Here we explicitly use the same encoding as that of the inbound message - this is important with GenericParser, which might use a different encoding by default
					outgoingMessageString = myParser.encode(response, myParser.getEncoding(incomingMessageString));
					
					Terser t = new Terser(response);
					outgoingMessageCharset = t.get_Renamed("MSH-18");
				}
				catch (System.Exception e)
				{
					outgoingMessageString = Responder.logAndMakeErrorMessage(e, (Segment) incomingMessageObject.get_Renamed("MSH"), myParser, myParser.getEncoding(incomingMessageString));
				}
			}
			
			return new System.String[]{outgoingMessageString, outgoingMessageCharset};
		}
Ejemplo n.º 37
0
		private void  parse(SupportClass.Tokenizer tok, Message message, StructRef root, NuGenEncodingCharacters ec)
		{
			
			Terser t = new Terser(message);
			
			lock (root)
			{
				StructRef ref_Renamed = root.getSuccessor("MSH");
				
				int field = 0;
				Segment segment = null;
				int[] fields = new int[0];
				
				while (tok.HasMoreTokens())
				{
					System.String token = tok.NextToken();
					if (token[0] == ec.FieldSeparator)
					{
						field++;
					}
					else if (token[0] == ourSegmentSeparator)
					{
						field = 0;
					}
					else if (field == 0)
					{
						StructRef newref = drill(ref_Renamed, token);
						if (newref == null)
						{
							segment = null;
							fields = new int[0];
						}
						else
						{
							ref_Renamed = newref;
							segment = t.getSegment(ref_Renamed.FullPath);
							fields = ref_Renamed.Fields;
						}
					}
					else if (segment != null && System.Array.BinarySearch(fields, (System.Object) field) >= 0)
					{
						parse(token, segment, field, ec);
					}
				}
				root.reset();
			}
		}
Ejemplo n.º 38
0
		/// <summary> Sends a message to a responder system, receives the reply, and 
		/// returns the reply as a Message object.  This method is thread-safe - multiple  
		/// threads can share an Initiator and call this method.  Responses are returned to 
		/// the calling thread on the basis of message ID.  
		/// </summary>
		public virtual Message sendAndReceive(Message out_Renamed)
		{
			
			if (out_Renamed == null)
				throw new NuGenHL7Exception("Can't encode null message", NuGenHL7Exception.REQUIRED_FIELD_MISSING);
			
			//register message with response Receiver(s) (by message ID)
			Terser t = new Terser(out_Renamed);
			System.String messID = t.get_Renamed("/MSH-10");
			NuGenMessageReceipt mr = this.conn.reserveResponse(messID);
			
			//log and send message 
			System.String outbound = conn.Parser.encode(out_Renamed);
			
			try
			{
				this.conn.SendWriter.writeMessage(outbound);
			}
			catch (System.IO.IOException e)
			{
				conn.close();
				throw e;
			}
			
			//wait for response
			bool done = false;
			Message response = null;
			long startTime = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
			while (!done)
			{
				lock (mr)
				{
					try
					{
						System.Threading.Monitor.Wait(mr, TimeSpan.FromMilliseconds(500)); //if it comes, notifyAll() will be called
					}
					catch (System.Threading.ThreadInterruptedException)
					{
					}
					
					if (mr.Message != null)
					{
						//get message from receipt 
						System.String inbound = mr.Message;
						
						//parse message
						response = conn.Parser.parse(inbound);
						done = true;
					}
					
					//if ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 > startTime + timeoutMillis)
						//throw new HL7Exception("Timeout waiting for response to message with control ID '" + messID);
				}
			}
			
			return response;
		}
Ejemplo n.º 39
0
		/// <summary> Logs the given exception and creates an error message to send to the
		/// remote system.
		/// 
		/// </summary>
		/// <param name="encoding">The encoding for the error message. If <code>null</code>, uses default encoding 
		/// </param>
		public static System.String logAndMakeErrorMessage(System.Exception e, Segment inHeader, Parser p, System.String encoding)
		{
			
			
			// create error message ...
			System.String errorMessage = null;
			try
			{
				Message out_Renamed = NuGenDefaultApplication.makeACK(inHeader);
				Terser t = new Terser(out_Renamed);
				
				//copy required data from incoming message ...
				try
				{
					t.set_Renamed("/MSH-10", MessageIDGenerator.Instance.NewID);
				}
				catch (System.IO.IOException ioe)
				{
					throw new NuGenHL7Exception("Problem creating error message ID: " + ioe.Message);
				}
				
				//populate MSA ...
				t.set_Renamed("/MSA-1", "AE"); //should this come from HL7Exception constructor?
				t.set_Renamed("/MSA-2", Terser.get_Renamed(inHeader, 10, 0, 1, 1));
				System.String excepMessage = e.Message;
				if (excepMessage != null)
					t.set_Renamed("/MSA-3", excepMessage.Substring(0, (System.Math.Min(80, excepMessage.Length)) - (0)));
				
				/* Some earlier ACKs don't have ERRs, but I think we'll change this within HAPI
				so that there is a single ACK for each version (with an ERR). */
				//see if it's an HL7Exception (so we can get specific information) ...
				if (e.GetType().Equals(typeof(NuGenHL7Exception)))
				{
					Segment err = (Segment) out_Renamed.get_Renamed("ERR");
					((NuGenHL7Exception) e).populate(err);
				}
				else
				{
					t.set_Renamed("/ERR-1-4-1", "207");
					t.set_Renamed("/ERR-1-4-2", "Application Internal Error");
					t.set_Renamed("/ERR-1-4-3", "HL70357");
				}
				
				if (encoding != null)
				{
					errorMessage = p.encode(out_Renamed, encoding);
				}
				else
				{
					errorMessage = p.encode(out_Renamed);
				}
			}
			catch (System.IO.IOException ioe)
			{
				throw new NuGenHL7Exception("IOException creating error response message: " + ioe.Message, NuGenHL7Exception.APPLICATION_INTERNAL_ERROR);
			}
			return errorMessage;
		}
		/// <summary> Returns the Applications that has been registered to handle 
		/// messages of the type and trigger event of the given message, or null if 
		/// there are none. 
		/// </summary>
		private NuGenApplication getMatchingApplication(Message message)
		{
			Terser t = new Terser(message);
			System.String messageType = t.get_Renamed("/MSH-9-1");
			System.String triggerEvent = t.get_Renamed("/MSH-9-2");
			return this.getMatchingApplication(messageType, triggerEvent);
		}
Ejemplo n.º 41
0
        /// <summary> Parses a segment string and populates the given Segment object.  Unexpected fields are
        /// added as Varies' at the end of the segment.
        ///
        /// </summary>
        /// <throws>  HL7Exception if the given string does not contain the </throws>
        /// <summary>      given segment or if the string is not encoded properly
        /// </summary>
        public virtual void  parse(Segment destination, System.String segment, NuGenEncodingCharacters encodingChars)
        {
            int fieldOffset = 0;

            if (isDelimDefSegment(destination.getName()))
            {
                fieldOffset = 1;
                //set field 1 to fourth character of string
                Terser.set_Renamed(destination, 1, 0, 1, 1, System.Convert.ToString(encodingChars.FieldSeparator));
            }

            System.String[] fields = split(segment, System.Convert.ToString(encodingChars.FieldSeparator));
            //destination.setName(fields[0]);
            for (int i = 1; i < fields.Length; i++)
            {
                System.String[] reps = split(fields[i], System.Convert.ToString(encodingChars.RepetitionSeparator));

                //MSH-2 will get split incorrectly so we have to fudge it ...
                bool isMSH2 = isDelimDefSegment(destination.getName()) && i + fieldOffset == 2;
                if (isMSH2)
                {
                    reps    = new System.String[1];
                    reps[0] = fields[i];
                }

                for (int j = 0; j < reps.Length; j++)
                {
                    try
                    {
                        System.Text.StringBuilder statusMessage = new System.Text.StringBuilder("Parsing field ");
                        statusMessage.Append(i + fieldOffset);
                        statusMessage.Append(" repetition ");
                        statusMessage.Append(j);
                        //parse(destination.getField(i + fieldOffset, j), reps[j], encodingChars, false);

                        Type field = destination.getField(i + fieldOffset, j);
                        if (isMSH2)
                        {
                            Terser.getPrimitive(field, 1, 1).Value = reps[j];
                        }
                        else
                        {
                            parse(field, reps[j], encodingChars);
                        }
                    }
                    catch (NuGenHL7Exception e)
                    {
                        //set the field location and throw again ...
                        e.FieldPosition     = i;
                        e.SegmentRepetition = MessageIterator.getIndex(destination.Parent, destination).rep;
                        e.SegmentName       = destination.getName();
                        throw e;
                    }
                }
            }

            //set data type of OBX-5
            if (destination.GetType().FullName.IndexOf("OBX") >= 0)
            {
                Varies.fixOBX5(destination, Factory);
            }
        }