1 /*
2 * SPDX-FileCopyrightText: none
3 * SPDX-License-Identifier: CC0-1.0
4 */
5
6 package dev.metaschema.core.metapath.impl;
7
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.List;
11
12 import dev.metaschema.core.metapath.item.IItem;
13 import dev.metaschema.core.metapath.item.ISequence;
14 import dev.metaschema.core.util.CollectionUtil;
15 import dev.metaschema.core.util.ObjectUtils;
16 import edu.umd.cs.findbugs.annotations.NonNull;
17
18 /**
19 * A Metapath sequence supporting an unbounded number of items.
20 *
21 * @param <ITEM>
22 * the Java type of the items
23 */
24 public class SequenceN<ITEM extends IItem>
25 extends AbstractSequence<ITEM> {
26 /**
27 * The singleton empty sequence instance.
28 * <p>
29 * This field is located in SequenceN rather than AbstractSequence to prevent
30 * class initialization deadlock. Since SequenceN extends AbstractSequence,
31 * AbstractSequence is always initialized first, ensuring no circular dependency
32 * when multiple threads initialize these classes concurrently.
33 */
34 @NonNull
35 private static final ISequence<?> EMPTY = new SequenceN<>();
36
37 /**
38 * Get an immutable sequence that is empty.
39 *
40 * @param <T>
41 * the item Java type
42 * @return the empty sequence
43 */
44 @SuppressWarnings("unchecked")
45 public static <T extends IItem> ISequence<T> empty() {
46 return (ISequence<T>) EMPTY;
47 }
48
49 @NonNull
50 private final List<ITEM> items;
51
52 /**
53 * Construct a new sequence with the provided items.
54 *
55 * @param items
56 * a collection containing the items to add to the sequence
57 * @param copy
58 * if {@code true} make a defensive copy of the list or {@code false}
59 * otherwise
60 */
61 public SequenceN(@NonNull List<ITEM> items, boolean copy) {
62 this.items = CollectionUtil.unmodifiableList(copy ? new ArrayList<>(items) : items);
63 }
64
65 /**
66 * Construct a new sequence with the provided items.
67 *
68 * @param items
69 * the items to add to the sequence
70 */
71 @SafeVarargs
72 public SequenceN(@NonNull ITEM... items) {
73 this(ObjectUtils.notNull(List.of(items)), false);
74 }
75
76 /**
77 * Construct a new sequence with the provided items.
78 *
79 * @param items
80 * a collection containing the items to add to the sequence
81 */
82 public SequenceN(@NonNull Collection<ITEM> items) {
83 this(new ArrayList<>(items), false);
84 }
85
86 /**
87 * Construct a new sequence with the provided items.
88 *
89 * @param items
90 * a list containing the items to add to the sequence
91 */
92 public SequenceN(@NonNull List<ITEM> items) {
93 this(items, false);
94 }
95
96 @Override
97 public List<ITEM> asList() {
98 return items;
99 }
100 }