1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.office.spreadsheet.rows;
22
23 import org.millscript.commons.alert.alerts.Unimplemented;
24 import org.millscript.commons.util.IList;
25 import org.millscript.commons.util.ListIterator;
26 import org.millscript.commons.util.alerts.ListIndexOutOfBoundsAlert;
27 import org.millscript.commons.util.iterator.NullListIterator;
28 import org.millscript.commons.util.list.AbstractIList;
29 import org.millscript.office.spreadsheet.Cell;
30 import org.millscript.office.spreadsheet.Row;
31
32 /**
33 *
34 */
35 public class ISharedRowList extends AbstractIList< Row > {
36
37 /**
38 * The index of the first element of this list in the backing store.
39 */
40 private final int firstIndex;
41
42 /**
43 * The index of the last element of this list in the backing store.
44 */
45 private final int lastIndex;
46
47 /**
48 * The backing data store for this worksheet, a two dimensional array,
49 * an array of array of cells. A null entry indicates the row is empty.
50 */
51 private Cell[][] rowData;
52
53 /**
54 * Constructs a new shared store worksheet with a slice of the specified
55 * backing row array.
56 *
57 * @param rows the backing object array(only kept if start <= end )
58 * @param start the index(one based, inclusive) of the first element in the
59 * slice
60 * @param end the index(one based, inclusive) of the last element in the
61 * slice. If end < start, the new list will be empty
62 */
63 public ISharedRowList( final Cell[][] rows, final int start, final int end ) {
64 if ( start > end ) {
65 this.rowData = null;
66 } else if ( start < 1 || start > rows.length ) {
67 throw new ListIndexOutOfBoundsAlert(
68 "First index in slice must be between 1 and the number of rows"
69 ).culprit(
70 "index",
71 start
72 ).decorate( rows ).mishap();
73 } else if ( end > rows.length ) {
74 throw new ListIndexOutOfBoundsAlert(
75 "Last index in slice must not be greater than the number of rows"
76 ).culprit(
77 "index",
78 end
79 ).decorate( rows ).mishap();
80 } else {
81 this.rowData = rows;
82 }
83 this.firstIndex = start;
84 this.lastIndex = end;
85 }
86
87 /**
88 * @see org.millscript.commons.util.list.AbstractIList#doGet(int)
89 */
90 @Override
91 protected Row doGet( final int pos ) {
92
93
94 final Cell[] row = this.rowData[ this.firstIndex - 2 + pos ];
95 if ( row == null ) {
96 return new RowImpl();
97 } else {
98 return new RowImpl( row, true );
99 }
100 }
101
102 /**
103 * @see org.millscript.commons.util.list.AbstractIList#doSlice(int, int, boolean)
104 */
105 @Override
106 protected IList< Row > doSlice( int first, int last, boolean share ) {
107
108
109 if ( share ) {
110 return new ISharedRowList(
111 this.rowData,
112 this.firstIndex + first - 1,
113 this.firstIndex + last - 1
114 );
115 } else {
116 return new IRowList(
117 this.rowData,
118 this.firstIndex + first - 1,
119 this.firstIndex + last - 1
120 );
121 }
122 }
123
124 /**
125 * @see org.millscript.commons.util.IList#indexOf(V)
126 */
127 public int indexOf( Row value ) {
128
129 throw new Unimplemented(
130 "A indexOf operation was required"
131 ).culprit( "class", this.getClass() );
132 }
133
134 /**
135 * @see org.millscript.commons.util.IList#iterator(boolean)
136 */
137 public ListIterator< Row > iterator( boolean share ) {
138 if ( share ) {
139 return new SharedRowListIterator(
140 this.rowData,
141 this.firstIndex,
142 this.lastIndex
143 );
144 } else if ( this.size() == 0 ) {
145 return new NullListIterator< Row >();
146 } else {
147 final Cell[][] objects = new Cell[ this.size() ][];
148 System.arraycopy( this.rowData, this.firstIndex - 1, objects, 0, objects.length );
149 return new RowListIterator( objects, true );
150 }
151 }
152
153 /**
154 * @see org.millscript.commons.util.IMap#size()
155 */
156 public int size() {
157 return this.lastIndex < this.firstIndex ? 0
158 : this.lastIndex - this.firstIndex + 1;
159 }
160
161 }