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