001/**
002The 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. 
004You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
005Software distributed under the License is distributed on an "AS IS" basis, 
006WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 
007specific language governing rights and limitations under the License. 
008
009The Original Code is "FiniteList.java".  Description: 
010"Holds a group of repetitions for a given Profile and exercises cardinality constraints" 
011
012The Initial Developer of the Original Code is University Health Network. Copyright (C) 
0132001.  All Rights Reserved. 
014
015Contributor(s): James Agnew
016                Paul Brohman
017                Mitch Delachevrotiere
018                Shawn Dyck
019                                Cory Metcalf 
020                                
021Alternatively, the contents of this file may be used under the terms of the 
022GNU General Public License (the "GPL"), in which case the provisions of the GPL are 
023applicable instead of those above.  If you wish to allow use of your version of this 
024file only under the terms of the GPL and not to allow others to use your version 
025of this file under the MPL, indicate your decision by deleting  the provisions above 
026and replace  them with the notice and other provisions required by the GPL License.  
027If you do not delete the provisions above, a recipient may use your version of 
028this file under either the MPL or the GPL. 
029
030*/
031package ca.uhn.hl7v2.conf.classes.abs;
032
033import ca.uhn.hl7v2.conf.classes.exceptions.*;
034import java.lang.reflect.*;
035import java.util.ArrayList;
036
037/** Holds a group of repetitions for a given Profile and exercises cardinality constraints
038 * @author <table><tr>James Agnew</tr>
039 *                <tr>Paul Brohman</tr>
040 *                <tr>Mitch Delachevrotiere</tr>
041 *                <tr>Shawn Dyck</tr>
042 *                                <tr>Cory Metcalf</tr></table>
043 */
044public class FiniteList {
045
046        private ArrayList<Repeatable> reps; // Stores the reps
047        private int maxReps; // The maximum allowable number of reps    
048//      private int minReps; // The minimum allowable number of reps    
049        private Class<? extends Repeatable> repType; // The type of repetition being stored here
050        private Object underlyingObject; // The underlying HAPI object
051
052        /** Constructor for FiniteList
053         * @param repType the Class which is repeating
054         * @param underlyingObject the underlying object that the extending class represents
055         */
056        public FiniteList(Class<? extends Repeatable> repType, Object underlyingObject) {
057                this.repType = repType;
058                this.underlyingObject = underlyingObject;
059
060                Repeatable firstRep = createRep(0);
061                this.maxReps = firstRep.getMaxReps();
062//              this.minReps = firstRep.getMinReps();
063
064                reps = new ArrayList<Repeatable>();
065                reps.add(firstRep);
066                createNewReps(maxReps);
067        }
068
069        /** Creates a new repetition
070         * @param rep the number representing the number of repetitions
071         */
072        private void createNewReps(int rep) {
073                while (reps.size() <= rep)
074                        reps.add(createRep(reps.size()));
075        }
076
077        /** Creates the repition
078         * @param rep the number representing which repition
079         */
080        private Repeatable createRep(int rep) {
081                try {
082                        Constructor<?> theCon = repType.getConstructors()[0];
083                        Repeatable thisRep = (Repeatable) theCon.newInstance(new Object[] { underlyingObject, rep});
084                        return thisRep;
085                } catch (InvocationTargetException e) {
086                        throw new ConformanceError("Error creating underlying repetition. This is a bug.\nError is: " + e.toString() + "\n" + e.getCause().toString());
087                } catch (Exception e) {
088                        throw new ConformanceError("Error creating underlying repetition. This is a bug. Error is: " + e.toString());
089                }
090        }
091
092        /**
093         * Returns the desired repetition
094         * @param rep The desired repetition number. Note that in accordance with the HL7 standard
095         * @return The desired repetition
096         * @throws ConformanceException if repetition is not accessible
097         */
098        public Repeatable getRep(int rep) throws ConfRepException {
099                if (rep < 1 || (maxReps != -1 && maxReps < rep))
100                        throw new ConfRepException(maxReps, rep);
101
102                rep--; // Decremented because HL7 standard wants 1-offset arrays
103                createNewReps(rep); // Create new reps if needed
104
105                return reps.get(rep);
106        }
107
108}