1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.doxia.index;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Objects;
26
27 import org.apache.maven.doxia.markup.Markup;
28 import org.apache.maven.doxia.sink.Sink;
29
30
31
32
33
34
35
36
37 public class IndexEntry {
38
39
40
41 private final IndexEntry parent;
42
43
44
45
46 private String id;
47
48
49
50
51 private boolean hasAnchor;
52
53
54
55
56 private String title;
57
58
59
60
61 private List<IndexEntry> childEntries = new ArrayList<>();
62
63 public enum Type {
64
65
66
67 UNKNOWN(),
68 SECTION_1(Sink.SECTION_LEVEL_1),
69 SECTION_2(Sink.SECTION_LEVEL_2),
70 SECTION_3(Sink.SECTION_LEVEL_3),
71 SECTION_4(Sink.SECTION_LEVEL_4),
72 SECTION_5(Sink.SECTION_LEVEL_5),
73 SECTION_6(Sink.SECTION_LEVEL_6),
74 DEFINED_TERM(),
75 FIGURE(),
76 TABLE();
77
78 private final int sectionLevel;
79
80 Type() {
81 this(-1);
82 }
83
84 Type(int sectionLevel) {
85 this.sectionLevel = sectionLevel;
86 }
87
88 static Type fromSectionLevel(int level) {
89 if (level < Sink.SECTION_LEVEL_1 || level > Sink.SECTION_LEVEL_6) {
90 throw new IllegalArgumentException("Level must be between " + Sink.SECTION_LEVEL_1 + " and "
91 + Sink.SECTION_LEVEL_6 + " but is " + level);
92 }
93 return Arrays.stream(Type.values())
94 .filter(t -> level == t.sectionLevel)
95 .findAny()
96 .orElseThrow(() -> new IllegalStateException("Could not find enum for sectionLevel " + level));
97 }
98 };
99
100
101
102
103 private final Type type;
104
105
106
107
108
109
110 public IndexEntry(String newId) {
111 this(null, newId);
112 }
113
114
115
116
117
118
119
120 public IndexEntry(IndexEntry newParent, String newId) {
121 this(newParent, newId, Type.UNKNOWN);
122 }
123
124
125
126
127
128
129
130
131 public IndexEntry(IndexEntry newParent, String newId, Type type) {
132 this.parent = newParent;
133 this.id = newId;
134
135 if (parent != null) {
136 parent.childEntries.add(this);
137 }
138 this.type = type;
139 }
140
141
142
143
144
145
146 public IndexEntry getParent() {
147 return parent;
148 }
149
150
151
152
153
154
155 public String getId() {
156 return id;
157 }
158
159
160
161
162
163
164
165 protected void setId(String id) {
166 this.id = id;
167 }
168
169
170
171
172
173
174 public Type getType() {
175 return type;
176 }
177
178
179
180
181
182
183 public void setAnchor(boolean hasAnchor) {
184 this.hasAnchor = hasAnchor;
185 }
186
187
188
189
190
191
192
193 public boolean hasAnchor() {
194 return hasAnchor;
195 }
196
197
198
199
200
201
202 public String getTitle() {
203 return title;
204 }
205
206
207
208
209
210
211 public void setTitle(String newTitle) {
212 this.title = newTitle;
213 }
214
215
216
217
218
219
220 public List<IndexEntry> getChildEntries() {
221 return Collections.unmodifiableList(childEntries);
222 }
223
224
225
226
227
228
229 public void setChildEntries(List<IndexEntry> entries) {
230 if (entries == null) {
231 childEntries = new ArrayList<>();
232 }
233
234 this.childEntries = entries;
235 }
236
237
238
239
240
241
242
243
244
245
246 public IndexEntry getNextEntry() {
247 if (parent == null) {
248 return null;
249 }
250
251 List<IndexEntry> entries = parent.getChildEntries();
252
253 int index = entries.indexOf(this);
254
255 if (index + 1 >= entries.size()) {
256 return null;
257 }
258
259 return entries.get(index + 1);
260 }
261
262
263
264
265
266
267 public IndexEntry getPrevEntry() {
268 if (parent == null) {
269 return null;
270 }
271
272 List<IndexEntry> entries = parent.getChildEntries();
273
274 int index = entries.indexOf(this);
275
276 if (index == 0) {
277 return null;
278 }
279
280 return entries.get(index - 1);
281 }
282
283
284
285
286
287
288 public IndexEntry getFirstEntry() {
289 List<IndexEntry> entries = getChildEntries();
290
291 if (entries.size() == 0) {
292 return null;
293 }
294
295 return entries.get(0);
296 }
297
298
299
300
301
302
303 public IndexEntry getLastEntry() {
304 List<IndexEntry> entries = getChildEntries();
305
306 if (entries.size() == 0) {
307 return null;
308 }
309
310 return entries.get(entries.size() - 1);
311 }
312
313
314
315
316
317
318 public IndexEntry getRootEntry() {
319 List<IndexEntry> entries = getChildEntries();
320
321 if (entries.size() == 0) {
322 return null;
323 } else if (entries.size() > 1) {
324 throw new IllegalStateException("This index has more than one root entry");
325 } else {
326 return entries.get(0);
327 }
328 }
329
330
331
332
333
334
335
336
337
338
339 public String toString() {
340 return toString(0);
341 }
342
343
344
345
346
347
348
349 public String toString(int depth) {
350 StringBuilder message = new StringBuilder();
351
352 message.append("Id: ").append(id);
353
354 if (title != null && !title.isEmpty()) {
355 message.append(", title: ").append(title);
356 }
357
358 message.append(Markup.EOL);
359
360 StringBuilder indent = new StringBuilder();
361
362 for (int i = 0; i < depth; i++) {
363 indent.append(" ");
364 }
365
366 for (IndexEntry entry : getChildEntries()) {
367 message.append(indent).append(entry.toString(depth + 1));
368 }
369
370 return message.toString();
371 }
372
373 @Override
374 public int hashCode() {
375 return Objects.hash(childEntries, hasAnchor, id, parent, title, type);
376 }
377
378 @Override
379 public boolean equals(Object obj) {
380 if (this == obj) {
381 return true;
382 }
383 if (obj == null) {
384 return false;
385 }
386 if (getClass() != obj.getClass()) {
387 return false;
388 }
389 IndexEntry other = (IndexEntry) obj;
390 return Objects.equals(childEntries, other.childEntries)
391 && hasAnchor == other.hasAnchor
392 && Objects.equals(id, other.id)
393 && Objects.equals(parent, other.parent)
394 && Objects.equals(title, other.title)
395 && type == other.type;
396 }
397 }