001/**
002 * The 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.
004 * You may obtain a copy of the License at http://www.mozilla.org/MPL/
005 * Software distributed under the License is distributed on an "AS IS" basis,
006 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
007 * specific language governing rights and limitations under the License.
008 *
009 * The Original Code is "TSComponentOne.java".  Description:
010 * "Represents an HL7 timestamp, which is related to the HL7 TS type."
011 *
012 * The Initial Developer of the Original Code is University Health Network. Copyright (C)
013 * 2005.  All Rights Reserved.
014 *
015 * Contributor(s): ______________________________________.
016 *
017 * Alternatively, the contents of this file may be used under the terms of the
018 * GNU General Public License (the "GPL"), in which case the provisions of the GPL are
019 * applicable instead of those above.  If you wish to allow use of your version of this
020 * file only under the terms of the GPL and not to allow others to use your version
021 * of this file under the MPL, indicate your decision by deleting  the provisions above
022 * and replace  them with the notice and other provisions required by the GPL License.
023 * If you do not delete the provisions above, a recipient may use your version of
024 * this file under either the MPL or the GPL.
025 */
026
027package ca.uhn.hl7v2.model.primitive;
028
029import java.util.Calendar;
030import java.util.Date;
031
032import ca.uhn.hl7v2.HL7Exception;
033import ca.uhn.hl7v2.model.AbstractPrimitive;
034import ca.uhn.hl7v2.model.DataTypeException;
035import ca.uhn.hl7v2.model.Message;
036
037/**
038 * Represents an HL7 timestamp, which is related to the HL7 TS type.  In version 2.5, 
039 * TS is a composite type.  The first component is type DTM, which corresponds to this class
040 * (actually model.v25.datatype.DTM inherits from this class at time of writing).  In HL7 versions 
041 * 2.2-2.4, it wasn't perfectly clear whether TS was composite or primitive.  HAPI interprets  
042 * it as composite, with the first component having a type that isn't defined by HL7, and we call 
043 * this type TSComponentOne.  In v2.1, TS is primitive, and corresponds one-to-one with this class.   
044 *  
045 * @author <a href="mailto:neal.acharya@uhn.on.ca">Neal Acharya</a>
046 * @author <a href="mailto:bryan.tripp@uhn.on.ca">Bryan Tripp</a>
047 * @version $Revision: 1.2 $ updated on $Date: 2011-02-21 17:55:08 $ by $Author: jamesagnew $
048 */
049@SuppressWarnings("serial")
050public abstract class TSComponentOne extends AbstractPrimitive {
051
052    private CommonTS myDetail;
053    
054    /**
055     * @param theMessage message to which this Type belongs
056     */
057    public TSComponentOne(Message theMessage) {
058        super(theMessage);
059    }
060
061    private CommonTS getDetail() throws DataTypeException {
062        if (myDetail == null) {
063            myDetail = new CommonTS(getValue());
064        }
065        return myDetail;
066    }
067    
068    /**
069     * @see AbstractPrimitive#setValue(java.lang.String)
070     * @throws DataTypeException if the value is incorrectly formatted and either validation is 
071     *      enabled for this primitive or detail setters / getters have been called, forcing further
072     *      parsing.   
073     */
074    public void setValue(String theValue) throws DataTypeException {
075        super.setValue(theValue);
076        
077        if (myDetail != null) {
078            myDetail.setValue(theValue);
079        }
080    }
081    
082    /**
083     * @see AbstractPrimitive#getValue
084     */
085    public String getValue() {
086        String result = super.getValue();
087        
088        if (myDetail != null) {
089            result = myDetail.getValue();
090        }
091        
092        return result;
093    }
094    
095    /**
096     * @see CommonTS#setDatePrecision(int, int, int)
097     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
098     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
099     *      this method is called.  
100     */
101    public void setDatePrecision(int yr, int mnth, int dy) throws DataTypeException {
102        getDetail().setDatePrecision(yr,mnth,dy);        
103    }
104    
105    /**
106     * @see CommonTS#setDateMinutePrecision(int, int, int, int, int)
107     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
108     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
109     *      this method is called.  
110     */
111    public void setDateMinutePrecision(int yr, int mnth, int dy, int hr, int min) throws DataTypeException {
112        getDetail().setDateMinutePrecision(yr,mnth,dy,hr,min);        
113    }
114    
115    /**
116     * @see CommonTS#setDateSecondPrecision(int, int, int, int, int, float)
117     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
118     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
119     *      this method is called.  
120     */
121    public void setDateSecondPrecision(int yr, int mnth, int dy, int hr, int min, float sec) throws DataTypeException {
122        getDetail().setDateSecondPrecision(yr,mnth,dy,hr,min,sec);        
123    }
124    
125    /**
126     * @see CommonTS#setOffset(int)
127     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
128     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
129     *      this method is called.  
130     */
131    public void setOffset(int signedOffset) throws DataTypeException {
132        getDetail().setOffset(signedOffset);        
133    }
134    
135    /**
136     * Returns the year as an integer.
137     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
138     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
139     *      this method is called.  
140     */
141    public int getYear() throws DataTypeException {
142        return getDetail().getYear();
143    }
144    
145    /**
146     * Returns the month as an integer.
147     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
148     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
149     *      this method is called.  
150     */
151    public int getMonth() throws DataTypeException {
152        return getDetail().getMonth();
153    }
154    
155    /**
156     * Returns the day as an integer.
157     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
158     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
159     *      this method is called.  
160     */
161    public int getDay() throws DataTypeException {
162        return getDetail().getDay();
163    }
164    
165    /**
166     * Returns the hour as an integer.
167     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
168     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
169     *      this method is called.  
170     */
171    public int getHour() throws DataTypeException {
172        return getDetail().getHour();
173    }
174    
175    /**
176     * Returns the minute as an integer.
177     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
178     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
179     *      this method is called.  
180     */
181    public int getMinute() throws DataTypeException {
182       return getDetail().getMinute();
183    }
184    
185    /**
186     * Returns the second as an integer.
187     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
188     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
189     *      this method is called.  
190     */
191    public int getSecond() throws DataTypeException {
192        return getDetail().getSecond();
193    }
194    
195    /**
196     * Returns the fractional second value as a float.
197     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
198     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
199     *      this method is called.  
200     */
201    public float getFractSecond() throws DataTypeException {
202        return getDetail().getFractSecond();
203    }
204    
205    /**
206     * Returns the GMT offset value as an integer.
207     * @throws DataTypeException if the value is incorrectly formatted.  If validation is enabled, this 
208     *      exception should be thrown at setValue(), but if not, detailed parsing may be deferred until 
209     *      this method is called.  
210     */
211    public int getGMTOffset() throws DataTypeException {
212        return getDetail().getGMTOffset();
213    }
214    
215    /**
216     * Convenience setter which sets the value using a {@link Calendar} object.
217     * 
218     * Note: Sets fields using precision up to the millisecond, including timezone offset
219     * 
220     * @param theCalendar The calendar object from which to retrieve values 
221     * @since 1.1 
222     */
223    public void setValue(Calendar theCalendar) throws DataTypeException {
224        setValue((String)null);
225        getDetail().setValue(theCalendar);
226    }
227
228    /**
229     * Convenience setter which sets the value using a {@link Calendar} object.
230     * 
231     * Note: Sets fields using precision up to the millisecond, and sets the timezone offset to
232     * the current system offset
233     * Note: Date is timezone-agnostic, representing always GMT time
234     * 
235     * @param theDate The date object from which to retrieve values 
236     * @since 1.1 
237     */
238    public void setValue(Date theDate) throws DataTypeException {
239        setValue((String)null);
240        getDetail().setValue(theDate);
241    }
242    
243    /**
244     * Convenience setter which sets the value using a {@link Calendar} object.
245     * 
246     * Note: Sets fields using precision up to the minute
247     * 
248     * @param theCalendar The calendar object from which to retrieve values 
249     * @since 1.1 
250     */
251    public void setValueToMinute(Calendar theCalendar) throws DataTypeException {
252        setValue((String)null);
253        getDetail().setValueToMinute(theCalendar);
254    }
255
256    /**
257     * Convenience setter which sets the value using a {@link Date} object.
258     * 
259     * Note: Sets fields using precision up to the minute
260     * Note: Date is timezone-agnostic, representing always GMT time
261     * 
262     * @param theDate The date object from which to retrieve values 
263     * @since 1.1 
264     */
265    public void setValueToMinute(Date theDate) throws DataTypeException {
266        setValue((String)null);
267        getDetail().setValueToMinute(theDate);
268    }
269
270    /**
271     * Convenience setter which sets the value using a {@link Calendar} object.
272     * 
273     * Note: Sets fields using precision up to the second
274     * 
275     * @param theCalendar The calendar object from which to retrieve values 
276     * @since 1.1 
277     */
278    public void setValueToSecond(Calendar theCalendar) throws DataTypeException {
279        setValue((String)null);
280        getDetail().setValueToSecond(theCalendar);
281    }
282
283    /**
284     * Convenience setter which sets the value using a {@link Date} object.
285     * 
286     * Note: Sets fields using precision up to the second
287     * 
288     * @param theDate The date object from which to retrieve values 
289     * @since 1.1 
290     */
291    public void setValueToSecond(Date theDate) throws DataTypeException {
292        setValue((String)null);
293        getDetail().setValueToSecond(theDate);
294    }
295
296    /**
297     * Return the value as a calendar object
298     * @since 1.1 
299     * @throws DataTypeException If the current underlying string representation can not be parsed into a valid date/time
300     */
301    public Calendar getValueAsCalendar() throws DataTypeException {
302        return getDetail().getValueAsCalendar();
303    }
304
305    /**
306     * Return the value as a date object
307     * Note: Sets fields using precision up to the second
308     * 
309     * @since 1.1 
310     * @throws DataTypeException If the current underlying string representation can not be parsed into a valid date/time
311     */
312    public Date getValueAsDate() throws DataTypeException {
313        return getDetail().getValueAsDate();
314    }
315
316    @Override
317    public boolean isEmpty() throws HL7Exception {
318        return super.isEmpty() && myDetail == null;
319    }
320
321    @Override
322    public void clear() {
323        super.clear();
324        myDetail = null;
325    }
326}