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 public boolean isSection() {
100 return sectionLevel >= 1;
101 }
102 }
103
104
105
106
107 private final Type type;
108
109
110
111
112
113
114 public IndexEntry(String newId) {
115 this(null, newId);
116 }
117
118
119
120
121
122
123
124 public IndexEntry(IndexEntry newParent, String newId) {
125 this(newParent, newId, Type.UNKNOWN);
126 }
127
128
129
130
131
132
133
134
135 public IndexEntry(IndexEntry newParent, String newId, Type type) {
136 this.parent = newParent;
137 this.id = newId;
138
139 if (parent != null) {
140 parent.childEntries.add(this);
141 }
142 this.type = type;
143 }
144
145
146
147
148
149
150 public IndexEntry getParent() {
151 return parent;
152 }
153
154
155
156
157
158
159 public String getId() {
160 return id;
161 }
162
163
164
165
166
167 public boolean hasId() {
168 return id != null;
169 }
170
171
172
173
174
175
176
177 protected void setId(String id) {
178 this.id = id;
179 }
180
181
182
183
184
185
186 public Type getType() {
187 return type;
188 }
189
190
191
192
193
194
195 public void setAnchor(boolean hasAnchor) {
196 this.hasAnchor = hasAnchor;
197 }
198
199
200
201
202
203
204
205 public boolean hasAnchor() {
206 return hasAnchor;
207 }
208
209
210
211
212
213
214 public String getTitle() {
215 return title;
216 }
217
218
219
220
221
222
223 public void setTitle(String newTitle) {
224 this.title = newTitle;
225 }
226
227
228
229
230
231
232 public List<IndexEntry> getChildEntries() {
233 return Collections.unmodifiableList(childEntries);
234 }
235
236
237
238
239
240
241 public void setChildEntries(List<IndexEntry> entries) {
242 if (entries == null) {
243 childEntries = new ArrayList<>();
244 }
245
246 this.childEntries = entries;
247 }
248
249
250
251
252
253
254
255
256
257
258 public IndexEntry getNextEntry() {
259 if (parent == null) {
260 return null;
261 }
262
263 List<IndexEntry> entries = parent.getChildEntries();
264
265 int index = entries.indexOf(this);
266
267 if (index + 1 >= entries.size()) {
268 return null;
269 }
270
271 return entries.get(index + 1);
272 }
273
274
275
276
277
278
279 public IndexEntry getPrevEntry() {
280 if (parent == null) {
281 return null;
282 }
283
284 List<IndexEntry> entries = parent.getChildEntries();
285
286 int index = entries.indexOf(this);
287
288 if (index == 0) {
289 return null;
290 }
291
292 return entries.get(index - 1);
293 }
294
295
296
297
298
299
300 public IndexEntry getFirstEntry() {
301 List<IndexEntry> entries = getChildEntries();
302
303 if (entries.size() == 0) {
304 return null;
305 }
306
307 return entries.get(0);
308 }
309
310
311
312
313
314
315 public IndexEntry getLastEntry() {
316 List<IndexEntry> entries = getChildEntries();
317
318 if (entries.size() == 0) {
319 return null;
320 }
321
322 return entries.get(entries.size() - 1);
323 }
324
325
326
327
328
329
330 public IndexEntry getRootEntry() {
331 List<IndexEntry> entries = getChildEntries();
332
333 if (entries.size() == 0) {
334 return null;
335 } else if (entries.size() > 1) {
336 throw new IllegalStateException("This index has more than one root entry");
337 } else {
338 return entries.get(0);
339 }
340 }
341
342
343
344
345
346
347
348
349
350
351 public String toString() {
352 return toString(0);
353 }
354
355
356
357
358
359
360
361 public String toString(int depth) {
362 StringBuilder message = new StringBuilder();
363
364 message.append("Id: ").append(id);
365
366 if (title != null && !title.isEmpty()) {
367 message.append(", title: ").append(title);
368 }
369
370 message.append(Markup.EOL);
371
372 StringBuilder indent = new StringBuilder();
373
374 for (int i = 0; i < depth; i++) {
375 indent.append(" ");
376 }
377
378 for (IndexEntry entry : getChildEntries()) {
379 message.append(indent).append(entry.toString(depth + 1));
380 }
381
382 return message.toString();
383 }
384
385 @Override
386 public int hashCode() {
387 return Objects.hash(childEntries, hasAnchor, id, parent, title, type);
388 }
389
390 @Override
391 public boolean equals(Object obj) {
392 if (this == obj) {
393 return true;
394 }
395 if (obj == null) {
396 return false;
397 }
398 if (getClass() != obj.getClass()) {
399 return false;
400 }
401 IndexEntry other = (IndexEntry) obj;
402 return Objects.equals(childEntries, other.childEntries)
403 && hasAnchor == other.hasAnchor
404 && Objects.equals(id, other.id)
405 && Objects.equals(parent, other.parent)
406 && Objects.equals(title, other.title)
407 && type == other.type;
408 }
409 }