001 /** 002 The contents of this file are subject to the Mozilla Public License Version 1.1 003 (the "License"); you may not use this file except in compliance with the License. 004 You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005 Software distributed under the License is distributed on an "AS IS" basis, 006 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007 specific language governing rights and limitations under the License. 008 009 The Original Code is "AbstractMessage.java". Description: 010 "A default implementation of Message" 011 012 The Initial Developer of the Original Code is University Health Network. Copyright (C) 013 2001. All Rights Reserved. 014 015 Contributor(s): ______________________________________. 016 017 Alternatively, the contents of this file may be used under the terms of the 018 GNU General Public License (the ???GPL???), in which case the provisions of the GPL are 019 applicable instead of those above. If you wish to allow use of your version of this 020 file only under the terms of the GPL and not to allow others to use your version 021 of this file under the MPL, indicate your decision by deleting the provisions above 022 and replace them with the notice and other provisions required by the GPL License. 023 If you do not delete the provisions above, a recipient may use your version of 024 this file under either the MPL or the GPL. 025 026 */ 027 028 package ca.uhn.hl7v2.model; 029 030 import java.io.IOException; 031 import java.util.regex.Matcher; 032 import java.util.regex.Pattern; 033 034 import ca.uhn.hl7v2.HL7Exception; 035 import ca.uhn.hl7v2.app.DefaultApplication; 036 import ca.uhn.hl7v2.model.primitive.ID; 037 import ca.uhn.hl7v2.parser.ModelClassFactory; 038 import ca.uhn.hl7v2.parser.Parser; 039 import ca.uhn.hl7v2.parser.PipeParser; 040 import ca.uhn.hl7v2.validation.ValidationContext; 041 042 /** 043 * A default implementation of Message. 044 * @author Bryan Tripp (bryan_tripp@sourceforge.net) 045 */ 046 public abstract class AbstractMessage extends AbstractGroup implements Message { 047 048 private ValidationContext myContext; 049 private static final Pattern ourVersionPattern = Pattern.compile("\\.(v2[0-9][0-9]?)\\."); 050 private String myVersion; 051 private transient Parser myParser; 052 053 /** 054 * @param theFactory factory for model classes (e.g. group, segment) for this message 055 */ 056 public AbstractMessage(ModelClassFactory theFactory) { 057 super(theFactory); 058 } 059 060 /** 061 * Returns this Message object - this is an implementation of the 062 * abstract method in AbstractGroup. 063 */ 064 public Message getMessage() { 065 return this; 066 } 067 068 /** 069 * Returns the version number. This default implementation inspects 070 * this.getClass().getName(). This should be overridden if you are putting 071 * a custom message definition in your own package, or it will default. 072 * @see Message#getVersion() 073 * @returns 2.4 if not obvious from package name 074 */ 075 public String getVersion() { 076 if (myVersion != null) { 077 return myVersion; 078 } 079 080 String version = null; 081 Pattern p = ourVersionPattern; 082 Matcher m = p.matcher(this.getClass().getName()); 083 if (m.find()) { 084 String verFolder = m.group(1); 085 if (verFolder.length() > 0) { 086 char[] chars = verFolder.toCharArray(); 087 StringBuffer buf = new StringBuffer(); 088 for (int i = 1; i < chars.length; i++) { //start at 1 to avoid the 'v' 089 buf.append(chars[i]); 090 if (i < chars.length - 1) buf.append('.'); 091 } 092 version = buf.toString(); 093 } 094 } 095 096 if (version == null) 097 version = "2.4"; 098 099 myVersion = version; 100 return version; 101 } 102 103 /** 104 * @return the set of validation rules that applies to this message 105 */ 106 public ValidationContext getValidationContext() { 107 return myContext; 108 } 109 110 /** 111 * @param theContext the set of validation rules that are to apply to this message 112 */ 113 public void setValidationContext(ValidationContext theContext) { 114 myContext = theContext; 115 } 116 117 /** 118 * {@inheritDoc } 119 */ 120 public Character getFieldSeparatorValue() throws HL7Exception { 121 Segment firstSegment = (Segment) get(getNames()[0]); 122 Primitive value = (Primitive) firstSegment.getField(1, 0); 123 String valueString = value.getValue(); 124 if (valueString == null || valueString.length() == 0) { 125 return null; 126 } 127 return valueString.charAt(0); 128 } 129 130 131 /** 132 * {@inheritDoc } 133 */ 134 public String getEncodingCharactersValue() throws HL7Exception { 135 Segment firstSegment = (Segment) get(getNames()[0]); 136 Primitive value = (Primitive) firstSegment.getField(2, 0); 137 return value.getValue(); 138 } 139 140 141 /** 142 * <p>Sets the parser to be used when parse/encode methods are called on this 143 * Message, as well as its children. It is recommended that if these methods 144 * are going to be called, a parser be supplied with the validation context 145 * wanted. Where possible, the parser should be reused for best performance, 146 * unless thread safety is an issue.</p> 147 * 148 * <p>Note that not all parsers can be used. As of version 1.0, only {@link PipeParser} 149 * supports this functionality</p> 150 * 151 * <p>Serialization note: The message parser is marked as transient, so it will not 152 * survive serialization.</p> 153 */ 154 public void setParser(Parser parser) { 155 if (parser == null) { 156 throw new NullPointerException("Value may not be null"); 157 } 158 159 myParser = parser; 160 } 161 162 163 /** 164 * <p>Returns the parser to be used when parse/encode methods are called on this 165 * Message, as well as its children. The default value is a new {@link PipeParser}.</p> 166 * 167 * <p>Serialization note: The message parser is marked as transient, so it will not 168 * survive serialization.</p> 169 */ 170 public Parser getParser() { 171 if (myParser == null) { 172 myParser = new PipeParser(); 173 } 174 175 return myParser; 176 } 177 178 179 /** 180 * {@inheritDoc } 181 */ 182 public void parse(String string) throws HL7Exception { 183 clear(); 184 getParser().parse(this, string); 185 } 186 187 188 /** 189 * {@inheritDoc } 190 */ 191 public String encode() throws HL7Exception { 192 return getParser().encode(this); 193 } 194 195 196 /** 197 * {@inheritDoc } 198 */ 199 public Message generateACK() throws HL7Exception, IOException { 200 return generateACK(null, null); 201 } 202 203 204 /** 205 * {@inheritDoc } 206 */ 207 public Message generateACK(String theAcknowledgementCode, HL7Exception theException) throws HL7Exception, IOException { 208 Message retVal = DefaultApplication.makeACK((Segment) get(getNames()[0])); 209 210 if (theAcknowledgementCode == null) { 211 theAcknowledgementCode = "AA"; 212 } 213 214 Segment msa = (Segment)retVal.get("MSA"); 215 ID ackCode = (ID) msa.getField(1, 0); 216 ackCode.setValue(theAcknowledgementCode); 217 218 if (theException != null) { 219 Segment err = (Segment) retVal.get("ERR"); 220 theException.populate(err, null); 221 } 222 223 return retVal; 224 } 225 226 }