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 "Varies.java". Description: 10 "Varies is a Type used as a placeholder for another Type in cases where 11 the appropriate Type is not known until run-time (e.g" 12 13 The Initial Developer of the Original Code is University Health Network. Copyright (C) 14 2001. All Rights Reserved. 15 16 Contributor(s): ______________________________________. 17 18 Alternatively, the contents of this file may be used under the terms of the 19 GNU General Public License (the "GPL"), in which case the provisions of the GPL are 20 applicable instead of those above. If you wish to allow use of your version of this 21 file only under the terms of the GPL and not to allow others to use your version 22 of this file under the MPL, indicate your decision by deleting the provisions above 23 and replace them with the notice and other provisions required by the GPL License. 24 If you do not delete the provisions above, a recipient may use your version of 25 this file under either the MPL or the GPL. 26 27 */ 28 29 package ca.uhn.hl7v2.model; 30 31 import ca.uhn.hl7v2.HL7Exception; 32 import ca.uhn.hl7v2.Location; 33 import ca.uhn.hl7v2.parser.EncodingCharacters; 34 import ca.uhn.hl7v2.parser.FixFieldDataType; 35 import ca.uhn.hl7v2.parser.ModelClassFactory; 36 import ca.uhn.hl7v2.parser.ParserConfiguration; 37 38 /** 39 * <p>Varies is a Type used as a placeholder for another Type in cases where 40 * the appropriate Type is not known until run-time (e.g. OBX-5). 41 * Parsers and validators may have logic that enforces restrictions on the 42 * Type based on other features of a segment.</p> 43 * <p>If you want to set both the type and the values of a Varies object, you should 44 * set the type first by calling setData(Type t), keeping a reference to your Type, 45 * and then set values by calling methods on the Type. Here is an example:</p> 46 * <p><code>CN cn = new CN();<br> 47 * variesObject.setData(cn);<br> 48 * cn.getIDNumber().setValue("foo");</code></p> 49 * 50 * @author Bryan Tripp (bryan_tripp@users.sourceforge.net) 51 * @author Andy Pardue 52 */ 53 @SuppressWarnings("serial") 54 public class Varies implements Variable { 55 56 /** 57 * System property key: The value may be set to provide a default 58 * datatype ("ST", "NM", etc) for an OBX segment with a missing 59 * OBX-2 value. 60 * 61 * @deprecated use FixFieldDataType#DEFAULT_OBX2_TYPE_PROP 62 */ 63 public static final String DEFAULT_OBX2_TYPE_PROP = FixFieldDataType.DEFAULT_OBX2_TYPE_PROP; 64 65 /** 66 * System property key: The value may be set to provide a default 67 * datatype ("ST", "NM", etc) for an OBX segment with an invalid 68 * OBX-2 value type. In other words, if OBX-2 has a value of "ZYZYZ", 69 * which is not a valid value, but this property is set to "ST", then 70 * OBX-5 will be parsed as an ST. 71 * 72 * @deprecated use FixOBX5#INVALID_OBX2_TYPE_PROP 73 */ 74 public static final String INVALID_OBX2_TYPE_PROP = FixFieldDataType.INVALID_OBX2_TYPE_PROP; 75 76 /** 77 * <p> 78 * System property key: If this is not set, or set to "true", and a subcomponent delimiter is found within the 79 * value of a Varies of a primitive type, this subcomponent delimiter will be treated as a literal 80 * character instead of a subcomponent delimiter, and will therefore be escaped if the message is 81 * re-encoded. This is handy when dealing with non-conformant sending systems which do not correctly 82 * escape ampersands in OBX-5 values. 83 * </p> 84 * <p> 85 * For example, consider the following OBX-5 segment: 86 * <pre> 87 * OBX||ST|||Apples, Pears & Bananas||| 88 * </pre> 89 * In this example, the data type is a primitive ST and does not support subcomponents, and the 90 * ampersand is obviously not intended to represent a subcomponent delimiter. If this 91 * property is set to <code>true</code>, the entire string will be treated as the 92 * value of OBX-5, and if the message is re-encoded the string will appear 93 * as "Apples, Pears \T\ Bananas". 94 * </p> 95 * <p> 96 * If this property is set to anything other than "true", the subcomponent delimiter is treated as a component delimiter, 97 * so the value after the ampersand is placed into an {@link ExtraComponents extra component}. 98 * </p> 99 * 100 * @deprecated use FixOBX5#ESCAPE_SUBCOMPONENT_DELIM_IN_PRIMITIVE 101 */ 102 public static final String ESCAPE_SUBCOMPONENT_DELIM_IN_PRIMITIVE = FixFieldDataType.ESCAPE_SUBCOMPONENT_DELIM_IN_PRIMITIVE; 103 104 105 private Type data; 106 private final Message message; 107 108 /** 109 * Creates new Varies. 110 * 111 * @param message message to which this type belongs 112 */ 113 public Varies(Message message) { 114 data = new GenericPrimitive(message); 115 this.message = message; 116 } 117 118 /** 119 * Returns the data contained by this instance of Varies. Returns a GenericPrimitive unless 120 * setData() has been called. 121 * 122 * @return the data contained by this instance of Varies 123 */ 124 public Type getData() { 125 return this.data; 126 } 127 128 public String getName() { 129 String name = "*"; 130 if (this.data != null) { 131 name = this.data.getName(); 132 } 133 return name; 134 } 135 136 /** 137 * Sets the data contained by this instance of Varies. If a data object already exists, 138 * then its values are copied to the incoming data object before the old one is replaced. 139 * For example, if getData() returns an ST with the value "19901012" and you call 140 * setData(new DT()), then subsequent calls to getData() will return the same DT, with the value 141 * set to "19901012". 142 * 143 * @param data the data to be set for this Varies instance 144 * @throws DataTypeException if the data could not be set 145 */ 146 public void setData(Type data) throws DataTypeException { 147 if (this.data != null) { 148 if (!(this.data instanceof Primitive"../../../../ca/uhn/hl7v2/model/Primitive.html#Primitive">Primitive) || ((Primitive) this.data).getValue() != null) { 149 ca.uhn.hl7v2.util.DeepCopy.copy(this.data, data); 150 } 151 } 152 this.data = data; 153 } 154 155 public ExtraComponents getExtraComponents() { 156 return this.data.getExtraComponents(); 157 } 158 159 /** 160 * @return the message to which this Type belongs 161 */ 162 public Message getMessage() { 163 return message; 164 } 165 166 /** 167 * <p> 168 * Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument 169 * is a Segment as opposed to a particular OBX because it is meant to work with any version. 170 * </p> 171 * <p> 172 * Note that if no value is present in OBX-2, or an invalid value is present in 173 * OBX-2, this method will throw an error. This behaviour can be corrected by using the 174 * following system properties: {@link #DEFAULT_OBX2_TYPE_PROP} and {@link #INVALID_OBX2_TYPE_PROP}, 175 * or by using configuration in {@link ParserConfiguration} 176 * </p> 177 * 178 * @param segment OBX segment instance to be modified 179 * @param factory ModelClassFactory to be used 180 * @throws HL7Exception if the operation fails 181 * @deprecated use FixOBX5#fixOBX5 182 */ 183 public static void fixOBX5(Segment segment, ModelClassFactory factory) throws HL7Exception { 184 FixFieldDataType.fixOBX5(segment, factory, segment.getMessage().getParser().getParserConfiguration()); 185 } 186 187 /** 188 * <p> 189 * Sets the data type of field 5 in the given OBX segment to the value of OBX-2. The argument 190 * is a Segment as opposed to a particular OBX because it is meant to work with any version. 191 * </p> 192 * <p> 193 * Note that if no value is present in OBX-2, or an invalid value is present in 194 * OBX-2, this method will throw an error. This behaviour can be corrected by using the 195 * following system properties: {@link #DEFAULT_OBX2_TYPE_PROP} and {@link #INVALID_OBX2_TYPE_PROP} 196 * or by using configuration in {@link ParserConfiguration} 197 * </p> 198 * 199 * @param segment OBX segment instance to be modified 200 * @param factory ModelClassFactory to be used 201 * @param parserConfiguration configuration that influences setting OBX-5 202 * @throws HL7Exception if the operation fails 203 * @deprecated use FixOBX5#fixOBX5 204 */ 205 public static void fixOBX5(Segment segment, ModelClassFactory factory, ParserConfiguration parserConfiguration) 206 throws HL7Exception { 207 FixFieldDataType.fixOBX5(segment, factory, parserConfiguration); 208 } 209 210 211 /** 212 * {@inheritDoc } 213 */ 214 public void parse(String string) throws HL7Exception { 215 if (data != null) { 216 data.clear(); 217 } 218 getMessage().getParser().parse(this, string, EncodingCharacters.getInstance(getMessage())); 219 } 220 221 /** 222 * {@inheritDoc } 223 */ 224 public String encode() throws HL7Exception { 225 return getMessage().getParser().doEncode(this, EncodingCharacters.getInstance(getMessage())); 226 } 227 228 /** 229 * {@inheritDoc } 230 */ 231 public void clear() { 232 data.clear(); 233 } 234 235 /** 236 * {@inheritDoc } 237 */ 238 public boolean isEmpty() throws HL7Exception { 239 return data.isEmpty(); 240 } 241 242 /** 243 * {@inheritDoc } 244 */ 245 public String toString() { 246 return AbstractType.toString(this); 247 } 248 249 public boolean accept(MessageVisitor visitor, Location currentLocation) throws HL7Exception { 250 return data.accept(visitor, currentLocation); 251 } 252 253 public Location/../ca/uhn/hl7v2/Location.html#Location">Location provideLocation(Location location, int index, int repetition) { 254 return data.provideLocation(location, index, repetition); 255 } 256 257 }