1 /*
2 * Prometheus: Application Framework
3 * Copyright 2012-2026. Tony Washer
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6 * use this file except in compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17 package io.github.tonywasher.joceanus.prometheus.service.sheet;
18
19 import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
20 import io.github.tonywasher.joceanus.oceanus.convert.OceanusDataConverter;
21 import io.github.tonywasher.joceanus.oceanus.date.OceanusDate;
22 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusDecimal;
23 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusMoney;
24 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusPrice;
25 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRate;
26 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusRatio;
27 import io.github.tonywasher.joceanus.oceanus.decimal.OceanusUnits;
28
29 /**
30 * Class representing a cell within a sheet or a view.
31 */
32 public abstract class PrometheusSheetCell {
33 /**
34 * The underlying row.
35 */
36 private final PrometheusSheetRow theRow;
37
38 /**
39 * The underlying view.
40 */
41 private final PrometheusSheetView theView;
42
43 /**
44 * The position of the cell.
45 */
46 private final PrometheusSheetCellPosition thePosition;
47
48 /**
49 * Is the cell readOnly?
50 */
51 private final boolean isReadOnly;
52
53 /**
54 * Constructor.
55 *
56 * @param pRow the row for the cell
57 * @param pColIndex the column index
58 * @param pReadOnly is the cell readOnly?
59 */
60 protected PrometheusSheetCell(final PrometheusSheetRow pRow,
61 final int pColIndex,
62 final boolean pReadOnly) {
63 /* Store parameters */
64 theRow = pRow;
65 theView = pRow.getView();
66 thePosition = new PrometheusSheetCellPosition(pColIndex, pRow.getRowIndex());
67 isReadOnly = pReadOnly;
68 }
69
70 /**
71 * Obtain the underlying sheet.
72 *
73 * @return the underlying sheet
74 */
75 public PrometheusSheetSheet getSheet() {
76 return theRow.getSheet();
77 }
78
79 /**
80 * Obtain the underlying row.
81 *
82 * @return the underlying row
83 */
84 public PrometheusSheetRow getRow() {
85 return theRow;
86 }
87
88 /**
89 * Obtain the underlying view.
90 *
91 * @return the underlying view
92 */
93 public PrometheusSheetView getView() {
94 return theView;
95 }
96
97 /**
98 * Obtain the cell position.
99 *
100 * @return position
101 */
102 public PrometheusSheetCellPosition getPosition() {
103 return thePosition;
104 }
105
106 /**
107 * Is the cell readOnly?
108 *
109 * @return true/false
110 */
111 public boolean isReadOnly() {
112 return isReadOnly;
113 }
114
115 /**
116 * Obtain the cell index.
117 *
118 * @return the index
119 */
120 public int getCellIndex() {
121 return thePosition.getColumnIndex();
122 }
123
124 /**
125 * Obtain boolean value of the cell.
126 *
127 * @return the boolean value
128 */
129 public abstract Boolean getBoolean();
130
131 /**
132 * Obtain date value of the cell.
133 *
134 * @return the date value
135 * @throws OceanusException on error
136 */
137 public abstract OceanusDate getDate() throws OceanusException;
138
139 /**
140 * Obtain integer value of the cell.
141 *
142 * @return the integer value
143 * @throws OceanusException on error
144 */
145 public abstract Integer getInteger() throws OceanusException;
146
147 /**
148 * Obtain long value of the cell.
149 *
150 * @return the long value
151 * @throws OceanusException on error
152 */
153 public abstract Long getLong() throws OceanusException;
154
155 /**
156 * Obtain long value of the cell.
157 *
158 * @return the long value
159 * @throws OceanusException on error
160 */
161 public Long getLongFromString() throws OceanusException {
162 try {
163 final String myValue = getString();
164 return Long.parseLong(myValue);
165 } catch (NumberFormatException e) {
166 throw new PrometheusSheetException("Failed to parse Long", e);
167 }
168 }
169
170 /**
171 * Obtain money value of the cell.
172 *
173 * @return the money value
174 * @throws OceanusException on error
175 */
176 public abstract OceanusMoney getMoney() throws OceanusException;
177
178 /**
179 * Obtain price value of the cell.
180 *
181 * @return the price value
182 * @throws OceanusException on error
183 */
184 public abstract OceanusPrice getPrice() throws OceanusException;
185
186 /**
187 * Obtain rate value of the cell.
188 *
189 * @return the rate value
190 * @throws OceanusException on error
191 */
192 public abstract OceanusRate getRate() throws OceanusException;
193
194 /**
195 * Obtain units value of the cell.
196 *
197 * @return the units value
198 * @throws OceanusException on error
199 */
200 public abstract OceanusUnits getUnits() throws OceanusException;
201
202 /**
203 * Obtain ratio value of the cell.
204 *
205 * @return the ratio value
206 * @throws OceanusException on error
207 */
208 public abstract OceanusRatio getRatio() throws OceanusException;
209
210 /**
211 * Obtain string value of the cell.
212 *
213 * @return the string value
214 */
215 public abstract String getString();
216
217 /**
218 * Obtain byte array value of the cell.
219 *
220 * @return the byte array value
221 */
222 public byte[] getBytes() {
223 final String myValue = getString();
224 return myValue == null
225 ? null
226 : OceanusDataConverter.base64ToByteArray(myValue);
227 }
228
229 /**
230 * Obtain char array value of the cell.
231 *
232 * @return the char array value
233 * @throws OceanusException on error
234 */
235 public char[] getCharArray() throws OceanusException {
236 final byte[] myValue = getBytes();
237 return myValue == null
238 ? null
239 : OceanusDataConverter.bytesToCharArray(myValue);
240 }
241
242 /**
243 * Set null value for the cell.
244 *
245 * @throws OceanusException on error
246 */
247 public void setNull() throws OceanusException {
248 /* Ignore readOnly */
249 if (!isReadOnly) {
250 setNullValue();
251 }
252 }
253
254 /**
255 * Set null value for the cell.
256 *
257 * @throws OceanusException on error
258 */
259 protected abstract void setNullValue() throws OceanusException;
260
261 /**
262 * Set boolean value of the cell.
263 *
264 * @param pValue the integer value
265 * @throws OceanusException on error
266 */
267 public void setBoolean(final Boolean pValue) throws OceanusException {
268 /* Ignore readOnly */
269 if (isReadOnly) {
270 return;
271 }
272
273 /* Handle null values */
274 if (pValue == null) {
275 setNullValue();
276 } else {
277 setBooleanValue(pValue);
278 }
279 }
280
281 /**
282 * Set non-null boolean value of the cell.
283 *
284 * @param pValue the integer value
285 * @throws OceanusException on error
286 */
287 protected abstract void setBooleanValue(Boolean pValue) throws OceanusException;
288
289 /**
290 * Set date value of the cell.
291 *
292 * @param pValue the date value
293 * @throws OceanusException on error
294 */
295 public void setDate(final OceanusDate pValue) throws OceanusException {
296 /* Ignore readOnly */
297 if (isReadOnly) {
298 return;
299 }
300
301 /* Handle null values */
302 if (pValue == null) {
303 setNullValue();
304 } else {
305 setDateValue(pValue);
306 }
307 }
308
309 /**
310 * Set non-null date value of the cell.
311 *
312 * @param pValue the integer value
313 * @throws OceanusException on error
314 */
315 protected abstract void setDateValue(OceanusDate pValue) throws OceanusException;
316
317 /**
318 * Set integer value of the cell.
319 *
320 * @param pValue the integer value
321 * @throws OceanusException on error
322 */
323 public void setInteger(final Integer pValue) throws OceanusException {
324 /* Ignore readOnly */
325 if (isReadOnly) {
326 return;
327 }
328
329 /* Handle null values */
330 if (pValue == null) {
331 setNullValue();
332 } else {
333 setIntegerValue(pValue);
334 }
335 }
336
337 /**
338 * Set non-null integer value of the cell.
339 *
340 * @param pValue the integer value
341 * @throws OceanusException on error
342 */
343 protected abstract void setIntegerValue(Integer pValue) throws OceanusException;
344
345 /**
346 * Set long value of the cell.
347 *
348 * @param pValue the integer value
349 * @throws OceanusException on error
350 */
351 public void setLong(final Long pValue) throws OceanusException {
352 /* Ignore readOnly */
353 if (isReadOnly) {
354 return;
355 }
356
357 /* Handle null values */
358 if (pValue == null) {
359 setNullValue();
360 } else {
361 setLongValue(pValue);
362 }
363 }
364
365 /**
366 * Set long value of the cell.
367 *
368 * @param pValue the integer value
369 * @throws OceanusException on error
370 */
371 public void setLongAsString(final Long pValue) throws OceanusException {
372 /* Ignore readOnly */
373 if (isReadOnly) {
374 return;
375 }
376
377 /* Handle null values */
378 if (pValue == null) {
379 setNullValue();
380 } else {
381 setStringValue(Long.toString(pValue));
382 }
383 }
384
385 /**
386 * Set non-null long value of the cell.
387 *
388 * @param pValue the long value
389 * @throws OceanusException on error
390 */
391 protected abstract void setLongValue(Long pValue) throws OceanusException;
392
393 /**
394 * Set string value of the cell.
395 *
396 * @param pValue the string value
397 * @throws OceanusException on error
398 */
399 public void setString(final String pValue) throws OceanusException {
400 /* Ignore readOnly */
401 if (isReadOnly) {
402 return;
403 }
404
405 /* Handle null values */
406 if (pValue == null) {
407 setNullValue();
408 } else {
409 setStringValue(pValue);
410 }
411 }
412
413 /**
414 * Set non-null string value of the cell.
415 *
416 * @param pValue the string value
417 * @throws OceanusException on error
418 */
419 protected abstract void setStringValue(String pValue) throws OceanusException;
420
421 /**
422 * Set decimal value of the cell.
423 *
424 * @param pValue the decimal value
425 * @throws OceanusException on error
426 */
427 public void setDecimal(final OceanusDecimal pValue) throws OceanusException {
428 /* Ignore readOnly */
429 if (isReadOnly) {
430 return;
431 }
432
433 /* Handle null values */
434 if (pValue == null) {
435 setNullValue();
436 } else {
437 setDecimalValue(pValue);
438 }
439 }
440
441 /**
442 * Set non-null decimal value of the cell.
443 *
444 * @param pValue the decimal value
445 * @throws OceanusException on error
446 */
447 protected abstract void setDecimalValue(OceanusDecimal pValue) throws OceanusException;
448
449 /**
450 * Set monetary value of the cell.
451 *
452 * @param pValue the monetary value
453 * @throws OceanusException on error
454 */
455 public void setMonetary(final OceanusMoney pValue) throws OceanusException {
456 /* Ignore readOnly */
457 if (isReadOnly) {
458 return;
459 }
460
461 /* Handle null values */
462 if (pValue == null) {
463 setNullValue();
464 } else {
465 setMonetaryValue(pValue);
466 }
467 }
468
469 /**
470 * Set non-null monetary value of the cell.
471 *
472 * @param pValue the monetary value
473 * @throws OceanusException on error
474 */
475 protected abstract void setMonetaryValue(OceanusMoney pValue) throws OceanusException;
476
477 /**
478 * Set header value of the cell.
479 *
480 * @param pValue the string value
481 * @throws OceanusException on error
482 */
483 public void setHeader(final String pValue) throws OceanusException {
484 /* Handle null values */
485 if (pValue == null) {
486 setNullValue();
487 } else {
488 /* Set value */
489 setHeaderValue(pValue);
490 }
491 }
492
493 /**
494 * Set non-null header value of the cell.
495 *
496 * @param pValue the header value
497 * @throws OceanusException on error
498 */
499 protected abstract void setHeaderValue(String pValue) throws OceanusException;
500
501 /**
502 * Set byte array value of the cell.
503 *
504 * @param pValue the byte array value
505 * @throws OceanusException on error
506 */
507 public void setBytes(final byte[] pValue) throws OceanusException {
508 /* Ignore readOnly */
509 if (isReadOnly) {
510 return;
511 }
512
513 /* Handle null values */
514 if (pValue == null) {
515 setNullValue();
516 } else {
517 setStringValue(OceanusDataConverter.byteArrayToBase64(pValue));
518 }
519 }
520
521 /**
522 * Set char array value of the cell.
523 *
524 * @param pValue the byte array value
525 * @throws OceanusException on error
526 */
527 public void setCharArray(final char[] pValue) throws OceanusException {
528 /* Ignore readOnly */
529 if (isReadOnly) {
530 return;
531 }
532
533 /* Handle null values */
534 if (pValue == null) {
535 setNullValue();
536 } else {
537 final byte[] myBytes = OceanusDataConverter.charsToByteArray(pValue);
538 setStringValue(OceanusDataConverter.byteArrayToBase64(myBytes));
539 }
540 }
541
542 /**
543 * Obtain the required CellStyle.
544 *
545 * @param pValue the value
546 * @return the required CellStyle
547 */
548 protected static PrometheusSheetCellStyleType getCellStyle(final Object pValue) {
549 if (pValue instanceof OceanusPrice) {
550 return PrometheusSheetCellStyleType.PRICE;
551 }
552 if (pValue instanceof OceanusMoney) {
553 return PrometheusSheetCellStyleType.MONEY;
554 }
555 if (pValue instanceof OceanusUnits) {
556 return PrometheusSheetCellStyleType.UNITS;
557 }
558 if (pValue instanceof OceanusRate) {
559 return PrometheusSheetCellStyleType.RATE;
560 }
561 if (pValue instanceof OceanusRatio) {
562 return PrometheusSheetCellStyleType.RATIO;
563 }
564 if (pValue instanceof Boolean) {
565 return PrometheusSheetCellStyleType.BOOLEAN;
566 }
567 if (pValue instanceof Number) {
568 return PrometheusSheetCellStyleType.INTEGER;
569 }
570 if (pValue instanceof OceanusDate) {
571 return PrometheusSheetCellStyleType.DATE;
572 }
573 if (pValue instanceof String) {
574 return PrometheusSheetCellStyleType.STRING;
575 }
576 return null;
577 }
578 }