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}