001package ca.uhn.hl7v2.model; 002 003import java.io.Serializable; 004import java.util.ArrayList; 005import java.util.List; 006 007import ca.uhn.hl7v2.HL7Exception; 008 009/** 010 * A set of "extra" components (sub-components) that are not a standard part 011 * of a field (component) but have been added at runtime. The purpose is to allow 012 * processing of locally-defined extensions to datatypes without the need for a 013 * custom message definition. 014 * Extra components are not treated uniformly with standard components (e.g. 015 * they are not accessible through methods like Primitive.getValue() and 016 * Composite.getComponent()). To do so would blur the distinction between 017 * primitive and composite types (i.e. leaf and non-leaf nodes), which seems 018 * nice and polymorphic for a moment but actually isn't helpful. 019 * Furthermore, the auto-generated classes do not define accessors to extra 020 * components, because they are meant to encourage and enforce use of the standard 021 * message structure -- stepping outside the standard structure must be 022 * deliberate. 023 * Note that a uniformity of access to standard and extra components is provided 024 * by Terser. 025 * @author Bryan Tripp 026 */ 027public class ExtraComponents implements Serializable { 028 029 030 private static final long serialVersionUID = -2614683870975956395L; 031 032 private List<Variable> comps; 033 private Message message; 034 035 public ExtraComponents(Message message) { 036 this.comps = new ArrayList<Variable>(); 037 this.message = message; 038 } 039 040 /** 041 * Returns the number of existing extra components 042 * @return number of existing extra components 043 */ 044 public int numComponents() { 045 return comps.size(); 046 } 047 048 /** 049 * Returns true if extra components are empty 050 * @return true if extra components are empty, false otherwise 051 * @throws HL7Exception 052 */ 053 public boolean isEmpty() throws HL7Exception { 054 for (Variable varies : comps) { 055 if (!varies.isEmpty()) return false; 056 } 057 return true; 058 } 059 060 public Message getMessage() { 061 return message; 062 } 063 064 /** 065 * Returns the component at the given location, creating it 066 * and all preceeding components if necessary. 067 * 068 * @param comp the extra component number starting at 0 (i.e. 0 is the first 069 * extra component) 070 * @return component at the given index 071 */ 072 public Variable getComponent(int comp) { 073 ensureComponentAndPredecessorsExist(comp); 074 return this.comps.get(comp); 075 } 076 077 /** 078 * Checks that the component at the given location exists, and that 079 * all preceding components exist, creating any missing ones. 080 */ 081 private void ensureComponentAndPredecessorsExist(int comp) { 082 for (int i = this.comps.size(); i <= comp; i++) { 083 this.comps.add(new Varies(message)); 084 } 085 } 086 087 088 /** 089 * Clears all extra components 090 */ 091 void clear() { 092 comps.clear(); 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 @Override 099 public String toString() { 100 return "ExtraComponents" + comps; 101 } 102 103 104 105 106}