View Javadoc
1   package nom.tam.fits;
2   
3   /*
4    * #%L
5    * nom.tam FITS library
6    * %%
7    * Copyright (C) 1996 - 2024 nom-tam-fits
8    * %%
9    * This is free and unencumbered software released into the public domain.
10   *
11   * Anyone is free to copy, modify, publish, use, compile, sell, or
12   * distribute this software, either in source code form or as a compiled
13   * binary, for any purpose, commercial or non-commercial, and by any
14   * means.
15   *
16   * In jurisdictions that recognize copyright laws, the author or authors
17   * of this software dedicate any and all copyright interest in the
18   * software to the public domain. We make this dedication for the benefit
19   * of the public at large and to the detriment of our heirs and
20   * successors. We intend this dedication to be an overt act of
21   * relinquishment in perpetuity of all present and future rights to this
22   * software under copyright law.
23   *
24   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
28   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30   * OTHER DEALINGS IN THE SOFTWARE.
31   * #L%
32   */
33  
34  import java.util.Date;
35  
36  import nom.tam.fits.header.IFitsHeader;
37  
38  /**
39   * Builder pattern implementation for easy readable header card creation.
40   *
41   * @author nir
42   */
43  public class HeaderCardBuilder {
44  
45      /**
46       * the header to fill.
47       */
48      private final Header header;
49  
50      /**
51       * the current card to fill.
52       */
53      private HeaderCard card;
54  
55      /**
56       * the current selected key.
57       */
58      private IFitsHeader key;
59  
60      /**
61       * scale to use for decimal values.
62       */
63      private int precision = -1;
64  
65      /**
66       * constructor to the header card builder.
67       *
68       * @param header the header to fill.
69       * @param key    the first header card to set.
70       */
71      protected HeaderCardBuilder(Header header, IFitsHeader key) {
72          this.header = header;
73          card(key);
74      }
75  
76      /**
77       * get the current build card of the builder.
78       *
79       * @return the current card
80       */
81      public HeaderCard card() {
82          return card;
83      }
84  
85      /**
86       * switch focus to the card with the specified key. If the card does not exist the card will be created when the
87       * value or the comment is set.
88       *
89       * @param  newKey the new card to set
90       *
91       * @return        this
92       */
93      public HeaderCardBuilder card(IFitsHeader newKey) {
94          key = newKey;
95          card = header.getCard(key);
96          return this;
97      }
98  
99      /**
100      * set the comment of the current card. If the card does not exist yet the card is created with a null value, if the
101      * card needs a value use the value setter first!
102      *
103      * @param  newComment          the new comment to set.
104      *
105      * @return                     this
106      *
107      * @throws HeaderCardException if the card creation failed.
108      */
109     public HeaderCardBuilder comment(String newComment) throws HeaderCardException {
110         if (card == null) {
111             card = new HeaderCard(key.key(), (String) null, null);
112             header.addLine(card);
113         }
114         card.setComment(newComment);
115         return this;
116     }
117 
118     /**
119      * set the value of the current card.If the card did not exist yet the card will be created.
120      *
121      * @param  newValue            the new value to set.
122      *
123      * @return                     this
124      *
125      * @throws HeaderCardException if the card creation failed.
126      */
127     public HeaderCardBuilder value(boolean newValue) throws HeaderCardException {
128         if (card == null) {
129             card = new HeaderCard(key.key(), newValue, null);
130             header.addLine(card);
131         } else {
132             card.setValue(newValue);
133         }
134         return this;
135     }
136 
137     /**
138      * set the value of the current card. If the card did not exist yet the card will be created.
139      *
140      * @param  newValue            the new value to set.
141      *
142      * @return                     this
143      *
144      * @throws HeaderCardException if the card creation failed.
145      */
146     public HeaderCardBuilder value(Date newValue) throws HeaderCardException {
147         return value(FitsDate.getFitsDateString(newValue));
148     }
149 
150     /**
151      * Sets a new number value for the current card. If the card did not exist yet the card will be created.
152      *
153      * @param  value               the new number value to set.
154      *
155      * @return                     this
156      *
157      * @throws HeaderCardException if the card creation failed.
158      * @throws LongValueException  if the number value cannot be represented in the space available for it in the
159      *                                 80-character wide FITS header record.
160      */
161     public HeaderCardBuilder value(Number value) throws HeaderCardException, LongValueException {
162         if (card == null) {
163             card = new HeaderCard(key.key(), value, precision, null);
164             header.addLine(card);
165         } else {
166             card.setValue(value, precision);
167         }
168         return this;
169     }
170 
171     /**
172      * set the value of the current card.If the card did not exist yet the card will be created.
173      *
174      * @param  newValue            the new value to set.
175      *
176      * @return                     this
177      *
178      * @throws HeaderCardException if the card creation failed.
179      * @throws LongValueException  if the number value cannot be represented in the space available for it in the
180      *                                 80-character wide FITS header record.
181      */
182     public HeaderCardBuilder value(String newValue) throws HeaderCardException, LongValueException {
183         if (card == null) {
184             card = new HeaderCard(key.key(), newValue, null);
185             header.addLine(card);
186         } else {
187             card.setValue(newValue);
188         }
189         return this;
190     }
191 
192     /**
193      * Sets the number of decimals to show for the following decimal values. This method is now deprecated. Use
194      * {@link #precision(int)} instead.
195      *
196      * @param      decimals the new number of decimal places to show.
197      *
198      * @return              this
199      *
200      * @deprecated          Use {@link #precision(int)} instead.
201      */
202     @Deprecated
203     public HeaderCardBuilder scale(int decimals) {
204         precision = decimals;
205         return this;
206     }
207 
208     /**
209      * Sets the number of decimals to show for the following decimal values. Trailing zeroes will be ommitted.
210      *
211      * @param  decimals the number of decimals to show for the following decimal values.
212      *
213      * @return          this
214      *
215      * @since           1.16
216      */
217     public HeaderCardBuilder precision(int decimals) {
218         precision = decimals;
219         return this;
220     }
221 
222     /**
223      * This method has been deprecated. Please use {@link #autoPrecision()} instead.
224      *
225      * @return     this
226      *
227      * @deprecated Use {@link #autoPrecision()} instead
228      */
229     @Deprecated
230     public HeaderCardBuilder noScale() {
231         precision = -1;
232         return this;
233     }
234 
235     /**
236      * Use the native precision for the given number type. Trailing zeroes will be ommitted.
237      *
238      * @return this
239      *
240      * @since  1.16
241      */
242     public HeaderCardBuilder autoPrecision() {
243         precision = -1;
244         return this;
245     }
246 
247     /**
248      * Returns the FITS header object that this builder is used with
249      * 
250      * @return the filled header.
251      */
252     public Header header() {
253         return header;
254     }
255 }