1 package org.djutils.data;
2
3 import java.util.Collection;
4 import java.util.LinkedHashSet;
5 import java.util.Set;
6
7 import org.djutils.base.Identifiable;
8 import org.djutils.exceptions.Throw;
9 import org.djutils.immutablecollections.ImmutableArrayList;
10 import org.djutils.immutablecollections.ImmutableList;
11
12
13
14
15
16
17
18
19
20
21
22
23 public abstract class Table implements Iterable<Row>, Identifiable
24 {
25
26
27 private final String id;
28
29
30 private final String description;
31
32
33 private final ImmutableList<Column<?>> columns;
34
35
36
37
38
39
40
41
42
43 public Table(final String id, final String description, final Collection<Column<?>> columns)
44 {
45 Throw.whenNull(id, "Id may not be null.");
46 Throw.whenNull(description, "Description may not be null.");
47 Throw.whenNull(columns, "Columns may not be null.");
48 Throw.when(id.length() == 0, IllegalArgumentException.class, "id cannot be empty");
49 Throw.when(columns.size() == 0, IllegalArgumentException.class, "there should be at least one column");
50 Set<String> ids = new LinkedHashSet<>();
51 columns.forEach((column) -> ids.add(column.getId()));
52 Throw.when(ids.size() != columns.size(), IllegalArgumentException.class, "Duplicate column ids are not allowed.");
53 this.id = id;
54 this.description = description;
55 this.columns = new ImmutableArrayList<>(columns);
56 }
57
58 @Override
59 public String getId()
60 {
61 return this.id;
62 }
63
64
65
66
67
68 public String getDescription()
69 {
70 return this.description;
71 }
72
73
74
75
76
77 public ImmutableList<Column<?>> getColumns()
78 {
79 return this.columns;
80 }
81
82
83
84
85
86
87
88 public Column<?> getColumn(final int columnNumber)
89 {
90 return this.columns.get(columnNumber);
91 }
92
93
94
95
96
97 public int getNumberOfColumns()
98 {
99 return this.columns.size();
100 }
101
102
103
104
105
106
107
108 public int getColumnNumber(final Column<?> column)
109 {
110 Throw.when(!this.columns.contains(column), IllegalArgumentException.class, "Column %s is not in the table.",
111 column.getId());
112 return this.columns.indexOf(column);
113 }
114
115
116
117
118
119
120
121 public int getColumnNumber(final String columnId)
122 {
123 for (int columnNumber = 0; columnNumber < getNumberOfColumns(); columnNumber++)
124 {
125 if (this.columns.get(columnNumber).getId().equals(columnId))
126 {
127 return columnNumber;
128 }
129 }
130 throw new IllegalArgumentException("Column " + columnId + " is not in the table.");
131 }
132
133
134
135
136
137 public String[] getColumnIds()
138 {
139 String[] headers = new String[getNumberOfColumns()];
140 int index = 0;
141 for (Column<?> column : this.columns)
142 {
143 headers[index++] = column.getId();
144 }
145 return headers;
146 }
147
148
149
150
151
152 public String[] getColumnDescriptions()
153 {
154 String[] descriptions = new String[getNumberOfColumns()];
155 int index = 0;
156 for (Column<?> column : this.columns)
157 {
158 descriptions[index++] = column.getDescription();
159 }
160 return descriptions;
161 }
162
163
164
165
166
167 public Class<?>[] getColumnDataTypes()
168 {
169 Class<?>[] dataTypes = new Class[getNumberOfColumns()];
170 int index = 0;
171 for (Column<?> column : this.columns)
172 {
173 dataTypes[index++] = column.getValueType();
174 }
175 return dataTypes;
176 }
177
178
179
180
181
182
183
184
185
186
187 public String[] getColumnDataTypeStrings()
188 {
189 String[] dataTypes = new String[getNumberOfColumns()];
190 int index = 0;
191 for (Column<?> column : this.columns)
192 {
193 dataTypes[index++] = column.getValueType().getName();
194 }
195 return dataTypes;
196 }
197
198
199
200
201
202 public abstract boolean isEmpty();
203
204 @Override
205 public String toString()
206 {
207 return "Table [id=" + this.id + ", description=" + this.description + ", columns=" + this.columns + "]";
208 }
209
210 }