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 java.util.Collections;
20 import java.util.ListIterator;
21
22 /**
23 * Represents a view of a range of cells.
24 */
25 public class PrometheusSheetView {
26 /**
27 * Underlying Sheet.
28 */
29 private final PrometheusSheetSheet theSheet;
30
31 /**
32 * Base Cell Position.
33 */
34 private final PrometheusSheetCellPosition theBaseCell;
35
36 /**
37 * Number of rows in view.
38 */
39 private final int theNumRows;
40
41 /**
42 * Number of columns in view.
43 */
44 private final int theNumColumns;
45
46 /**
47 * Constructor.
48 *
49 * @param pSheet the sheet containing the view
50 * @param pFirstCell the first cell of the view
51 * @param pLastCell the last cell of the view
52 */
53 public PrometheusSheetView(final PrometheusSheetSheet pSheet,
54 final PrometheusSheetCellPosition pFirstCell,
55 final PrometheusSheetCellPosition pLastCell) {
56 /* Store parameters */
57 theSheet = pSheet;
58 theBaseCell = pFirstCell;
59 theNumRows = pLastCell.getRowIndex()
60 - pFirstCell.getRowIndex()
61 + 1;
62 theNumColumns = pLastCell.getColumnIndex()
63 - pFirstCell.getColumnIndex()
64 + 1;
65 }
66
67 /**
68 * Constructor.
69 *
70 * @param pFirstCell the first cell of the view
71 * @param pLastCell the last cell of the view
72 */
73 protected PrometheusSheetView(final PrometheusSheetCell pFirstCell,
74 final PrometheusSheetCell pLastCell) {
75 /* Store parameters */
76 this(pFirstCell.getSheet(), pFirstCell.getPosition(), pLastCell.getPosition());
77 }
78
79 /**
80 * Obtain the underlying sheet.
81 *
82 * @return the underlying sheet
83 */
84 public PrometheusSheetSheet getSheet() {
85 return theSheet;
86 }
87
88 /**
89 * Obtain the top left position.
90 *
91 * @return the top left position
92 */
93 public PrometheusSheetCellPosition getBaseCell() {
94 return theBaseCell;
95 }
96
97 /**
98 * Determine number of rows in this view.
99 *
100 * @return the number of rows.
101 */
102 public int getRowCount() {
103 return theNumRows;
104 }
105
106 /**
107 * Determine number of columns in this view.
108 *
109 * @return the number of columns.
110 */
111 public int getColumnCount() {
112 return theNumColumns;
113 }
114
115 /**
116 * Convert Row index.
117 *
118 * @param pRowIndex the view index
119 * @return the sheet index or -1 if outside view
120 */
121 protected int convertRowIndex(final int pRowIndex) {
122 /* Reject values outside range */
123 if (pRowIndex < 0
124 || pRowIndex >= theNumRows) {
125 return -1;
126 }
127
128 /* Return adjusted index */
129 return pRowIndex
130 + theBaseCell.getRowIndex();
131 }
132
133 /**
134 * Convert Column index.
135 *
136 * @param pColIndex the view index
137 * @return the sheet index or -1 if outside view
138 */
139 private int convertColumnIndex(final int pColIndex) {
140 /* Reject values outside range */
141 if (pColIndex < 0
142 || pColIndex >= theNumColumns) {
143 return -1;
144 }
145
146 /* Return adjusted index */
147 return pColIndex
148 + theBaseCell.getColumnIndex();
149 }
150
151 /**
152 * Obtain the row at required index.
153 *
154 * @param pRowIndex the requested row index
155 * @return the requested row.
156 */
157 public PrometheusSheetRow getRowByIndex(final int pRowIndex) {
158 /* Return the row */
159 final int myIndex = convertRowIndex(pRowIndex);
160 return myIndex < 0
161 ? null
162 : theSheet.getReadOnlyRowByIndex(myIndex);
163 }
164
165 /**
166 * Obtain the cell at required position.
167 *
168 * @param pColumnIndex the requested column index
169 * @param pRowIndex the requested row index
170 * @return the requested cell.
171 */
172 public PrometheusSheetCell getCellByPosition(final int pColumnIndex,
173 final int pRowIndex) {
174 /* Return the cell */
175 final PrometheusSheetCellPosition myPos = new PrometheusSheetCellPosition(pColumnIndex, pRowIndex);
176 return getCellByPosition(myPos);
177 }
178
179 /**
180 * Obtain the cell at required position.
181 *
182 * @param pPosition the requested position
183 * @return the requested cell.
184 */
185 public PrometheusSheetCell getCellByPosition(final PrometheusSheetCellPosition pPosition) {
186 /* Return the cell */
187 final PrometheusSheetRow myRow = getRowByIndex(pPosition.getRowIndex());
188 return myRow == null
189 ? null
190 : getRowCellByIndex(myRow, pPosition.getColumnIndex());
191 }
192
193 /**
194 * Obtain the cell at required index.
195 *
196 * @param pRow the row to extract from
197 * @param pIndex the requested index
198 * @return the requested cell.
199 */
200 public PrometheusSheetCell getRowCellByIndex(final PrometheusSheetRow pRow,
201 final int pIndex) {
202 /* Return the cell */
203 final int myIndex = convertColumnIndex(pIndex);
204 return myIndex < 0
205 ? null
206 : pRow.getReadOnlyCellByIndex(myIndex);
207 }
208
209 /**
210 * Obtain a cell iterator for non-empty cells in the view and in the row.
211 *
212 * @param pRow the row
213 * @return the iterator
214 */
215 public ListIterator<PrometheusSheetCell> cellIterator(final PrometheusSheetRow pRow) {
216 /* Check that the row is in the view */
217 final int myIndex = pRow.getRowIndex();
218 int myFirstIndex = theBaseCell.getRowIndex();
219 int myLastIndex = myFirstIndex + theNumRows - 1;
220
221 /* Return null iterator for row not in view */
222 if (myIndex < myFirstIndex
223 || myIndex > myLastIndex
224 || !theSheet.getName().equals(pRow.getSheet().getName())) {
225 return Collections.emptyListIterator();
226 }
227
228 /* return the iterator */
229 myFirstIndex = theBaseCell.getColumnIndex();
230 myLastIndex = myFirstIndex + theNumColumns - 1;
231 return pRow.iteratorForRange(myFirstIndex, myLastIndex);
232 }
233
234 /**
235 * Obtain a row iterator for non-empty rows in this view.
236 *
237 * @return the iterator
238 */
239 public ListIterator<PrometheusSheetRow> rowIterator() {
240 /* Obtain the iterator */
241 final int myFirstIndex = theBaseCell.getRowIndex();
242 final int myLastIndex = myFirstIndex + theNumRows - 1;
243 return theSheet.iteratorForRange(myFirstIndex, myLastIndex);
244 }
245 }