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<Varies> comps;
033    private Message message;
034
035    public ExtraComponents(Message message) {
036        this.comps = new ArrayList<Varies>();
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 (Varies varies : comps) {
055            if (!varies.isEmpty()) return false;
056        }
057        return true;
058    }
059    
060    
061    /** 
062     * Returns the component at the given location, creating it 
063     * and all preceeding components if necessary.
064     *
065     * @param comp the extra component number starting at 0 (i.e. 0 is the first 
066     *      extra component)
067     * @return component at the given index
068     */
069    public Varies getComponent(int comp) {
070        ensureComponentAndPredecessorsExist(comp);
071        return this.comps.get(comp);
072    }
073    
074    /**
075     * Checks that the component at the given location exists, and that 
076     * all preceding components exist, creating any missing ones.  
077     */
078    private void ensureComponentAndPredecessorsExist(int comp) {
079        for (int i = this.comps.size(); i <= comp; i++) {
080            this.comps.add(new Varies(message));
081        }
082    }
083
084
085        /**
086         * Clears all extra components
087         */
088        void clear() {
089                comps.clear();
090        }
091
092    /**
093     * {@inheritDoc}
094         */
095        @Override
096        public String toString() {
097                return "ExtraComponents" + comps;
098        }
099
100        
101        
102        
103}