1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.core.metapath;
28
29 import gov.nist.secauto.metaschema.core.metapath.item.IItem;
30 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
31
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Set;
37 import java.util.function.BiConsumer;
38 import java.util.function.BinaryOperator;
39 import java.util.function.Consumer;
40 import java.util.function.Function;
41 import java.util.function.Supplier;
42 import java.util.stream.Collector;
43 import java.util.stream.Stream;
44
45 import edu.umd.cs.findbugs.annotations.NonNull;
46 import edu.umd.cs.findbugs.annotations.Nullable;
47
48 public interface ISequence<ITEM_TYPE extends IItem> extends Iterable<ITEM_TYPE> {
49 @SuppressWarnings("rawtypes")
50 ISequence EMPTY = new EmptyListImpl<>();
51
52
53
54
55
56
57
58
59 @SuppressWarnings({ "unchecked", "null" })
60 @NonNull
61 static <ITEM_TYPE extends IItem> ISequence<ITEM_TYPE> empty() {
62 return EMPTY;
63 }
64
65
66
67
68
69
70
71
72
73
74
75
76 @NonNull
77 public static <ITEM_TYPE extends IItem> ISequence<ITEM_TYPE> of(
78 @Nullable ITEM_TYPE item) {
79 ISequence<ITEM_TYPE> retval;
80 if (item == null) {
81 retval = empty();
82 } else {
83 retval = new SingletonSequenceImpl<>(item);
84 }
85 return retval;
86 }
87
88
89
90
91
92
93
94
95
96
97 @NonNull
98 public static <ITEM_TYPE extends IItem> ISequence<ITEM_TYPE> of(
99 @NonNull List<ITEM_TYPE> items) {
100 ISequence<ITEM_TYPE> retval;
101 if (items.isEmpty()) {
102 retval = empty();
103 } else {
104 retval = new ListSequenceImpl<>(items);
105 }
106 return retval;
107 }
108
109
110
111
112
113
114
115
116
117
118
119 @NonNull
120 public static <ITEM_TYPE extends IItem> ISequence<ITEM_TYPE> of(
121 Stream<ITEM_TYPE> items) {
122 return items == null ? empty() : new StreamSequenceImpl<>(items);
123 }
124
125 @Override
126 default Iterator<ITEM_TYPE> iterator() {
127 return asList().listIterator();
128 }
129
130
131
132
133
134
135 @NonNull
136 List<ITEM_TYPE> asList();
137
138
139
140
141
142
143
144 @NonNull
145 Stream<ITEM_TYPE> asStream();
146
147
148
149
150
151
152
153 void collect();
154
155
156
157
158
159
160
161 boolean isEmpty();
162
163
164
165
166
167
168 int size();
169
170
171
172
173
174
175
176 @Override
177 void forEach(Consumer<? super ITEM_TYPE> action);
178
179 @NonNull
180 static <ITEM_TYPE extends IItem> Collector<ITEM_TYPE, ?, ISequence<ITEM_TYPE>> toSequence() {
181
182 return new Collector<ITEM_TYPE, List<ITEM_TYPE>, ISequence<ITEM_TYPE>>() {
183
184 @Override
185 public Supplier<List<ITEM_TYPE>> supplier() {
186 return ArrayList::new;
187 }
188
189 @Override
190 public BiConsumer<List<ITEM_TYPE>, ITEM_TYPE> accumulator() {
191 return (list, value) -> list.add(value);
192 }
193
194 @Override
195 public BinaryOperator<List<ITEM_TYPE>> combiner() {
196 return (list1, list2) -> {
197 list1.addAll(list2);
198 return list1;
199 };
200 }
201
202 @Override
203 public Function<List<ITEM_TYPE>, ISequence<ITEM_TYPE>> finisher() {
204 return list -> {
205 ISequence<ITEM_TYPE> retval;
206 if (list.isEmpty()) {
207 retval = empty();
208 } else if (list.size() == 1) {
209 retval = new SingletonSequenceImpl<>(ObjectUtils.notNull(list.iterator().next()));
210 } else {
211 retval = new ListSequenceImpl<>(list, false);
212 }
213 return retval;
214 };
215 }
216
217 @Override
218 public Set<Characteristics> characteristics() {
219 return Collections.emptySet();
220 }
221
222 };
223 }
224 }