1 package org.apache.maven.api.settings;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.Serializable;
23 import java.util.AbstractList;
24 import java.util.AbstractMap;
25 import java.util.AbstractSet;
26 import java.util.Collection;
27 import java.util.Comparator;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.ListIterator;
31 import java.util.Map;
32 import java.util.NoSuchElementException;
33 import java.util.Properties;
34 import java.util.RandomAccess;
35 import java.util.Set;
36 import java.util.function.BiFunction;
37 import java.util.function.Function;
38 import java.util.function.Predicate;
39 import java.util.function.UnaryOperator;
40
41 class ImmutableCollections
42 {
43
44 private static final List<?> EMPTY_LIST = new AbstractImmutableList<Object>()
45 {
46 @Override
47 public Object get( int index )
48 {
49 throw new IndexOutOfBoundsException();
50 }
51 @Override
52 public int size()
53 {
54 return 0;
55 }
56 };
57
58 private static final Map<?, ?> EMPTY_MAP = new AbstractImmutableMap<Object, Object>()
59 {
60 @Override
61 public Set<Entry<Object, Object>> entrySet()
62 {
63 return new AbstractImmutableSet<Entry<Object, Object>>()
64 {
65 @Override
66 public Iterator<Entry<Object, Object>> iterator()
67 {
68 return new Iterator<Entry<Object, Object>>()
69 {
70 @Override
71 public boolean hasNext()
72 {
73 return false;
74 }
75 @Override
76 public Entry<Object, Object> next()
77 {
78 throw new NoSuchElementException();
79 }
80 };
81 }
82 @Override
83 public int size()
84 {
85 return 0;
86 }
87 };
88 }
89 };
90
91 static <E> List<E> copy( Collection<E> collection )
92 {
93 if ( collection == null )
94 {
95 return emptyList();
96 }
97 else if ( collection instanceof AbstractImmutableList )
98 {
99 return ( List<E> ) collection;
100 }
101 else
102 {
103 switch ( collection.size() )
104 {
105 case 0:
106 return emptyList();
107 case 1:
108 return singletonList( collection.iterator().next() );
109 case 2:
110 Iterator<E> it = collection.iterator();
111 return new List2<>( it.next(), it.next() );
112 default:
113 return new ListN<>( collection );
114 }
115 }
116 }
117
118 @SuppressWarnings( "unchecked" )
119 static <E> List<E> emptyList()
120 {
121 return ( List<E> ) EMPTY_LIST;
122 }
123
124 static <E> List<E> singletonList( E element )
125 {
126 return new List1<>( element );
127 }
128
129 static <K, V> Map<K, V> copy( Map<K, V> map )
130 {
131 if ( map == null )
132 {
133 return emptyMap();
134 }
135 else if ( map instanceof AbstractImmutableMap )
136 {
137 return map;
138 }
139 else
140 {
141 switch ( map.size() )
142 {
143 case 0:
144 return emptyMap();
145 case 1:
146 Map.Entry<K, V> entry = map.entrySet().iterator().next();
147 return singletonMap( entry.getKey(), entry.getValue() );
148 default:
149 return new MapN<>( map );
150 }
151 }
152 }
153
154 @SuppressWarnings( "unchecked" )
155 static <K, V> Map<K, V> emptyMap()
156 {
157 return ( Map<K, V> ) EMPTY_MAP;
158 }
159
160 static <K, V> Map<K, V> singletonMap( K key, V value )
161 {
162 return new Map1<>( key, value );
163 }
164
165 static Properties copy( Properties properties )
166 {
167 if ( properties instanceof ROProperties )
168 {
169 return properties;
170 }
171 return new ROProperties( properties );
172 }
173
174 private static class List1<E> extends AbstractImmutableList<E>
175 {
176 private final E element;
177
178 private List1( E element )
179 {
180 this.element = element;
181 }
182
183 @Override
184 public E get( int index )
185 {
186 if ( index == 0 )
187 {
188 return element;
189 }
190 throw outOfBounds( index );
191 }
192
193 @Override
194 public int size()
195 {
196 return 1;
197 }
198 }
199
200 private static class List2<E> extends AbstractImmutableList<E>
201 {
202 private final E element1;
203 private final E element2;
204
205 private List2( E element1, E element2 )
206 {
207 this.element1 = element1;
208 this.element2 = element2;
209 }
210
211 @Override
212 public E get( int index )
213 {
214 if ( index == 0 )
215 {
216 return element1;
217 }
218 else if ( index == 1 )
219 {
220 return element2;
221 }
222 throw outOfBounds( index );
223 }
224
225 @Override
226 public int size()
227 {
228 return 2;
229 }
230 }
231
232 private static class ListN<E> extends AbstractImmutableList<E>
233 {
234 private final Object[] elements;
235
236 private ListN( Collection<E> elements )
237 {
238 this.elements = elements.toArray();
239 }
240
241 @SuppressWarnings( "unchecked" )
242 @Override
243 public E get( int index )
244 {
245 return ( E ) elements[ index ];
246 }
247
248 @Override
249 public int size()
250 {
251 return elements.length;
252 }
253 }
254
255 private abstract static class AbstractImmutableList<E>
256 extends AbstractList<E>
257 implements RandomAccess, Serializable
258 {
259 @Override
260 public boolean add( E e )
261 {
262 throw uoe();
263 }
264
265 @Override
266 public boolean remove( Object o )
267 {
268 throw uoe();
269 }
270
271 @Override
272 public boolean addAll( Collection<? extends E> c )
273 {
274 throw uoe();
275 }
276
277 @Override
278 public boolean removeAll( Collection<?> c )
279 {
280 throw uoe();
281 }
282
283 @Override
284 public boolean retainAll( Collection<?> c )
285 {
286 throw uoe();
287 }
288
289 @Override
290 public void clear()
291 {
292 throw uoe();
293 }
294
295 @Override
296 public boolean removeIf( Predicate<? super E> filter )
297 {
298 throw uoe();
299 }
300
301 @Override
302 public void replaceAll( UnaryOperator<E> operator )
303 {
304 throw uoe();
305 }
306
307 @Override
308 public void sort( Comparator<? super E> c )
309 {
310 throw uoe();
311 }
312
313 @Override
314 public Iterator<E> iterator()
315 {
316 return new Itr( 0 );
317 }
318
319 @Override
320 public ListIterator<E> listIterator()
321 {
322 return new Itr( 0 );
323 }
324
325 @Override
326 public ListIterator<E> listIterator( int index )
327 {
328 if ( index < 0 || index > size() )
329 {
330 throw outOfBounds( index );
331 }
332 return new Itr( index );
333 }
334
335 @Override
336 public List<E> subList( int fromIndex, int toIndex )
337 {
338 if ( fromIndex < 0 )
339 {
340 throw new IndexOutOfBoundsException( "fromIndex = " + fromIndex );
341 }
342 if ( toIndex > size() )
343 {
344 throw new IndexOutOfBoundsException( "toIndex = " + toIndex );
345 }
346 if ( fromIndex > toIndex )
347 {
348 throw new IllegalArgumentException( "fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")" );
349 }
350 return new SubList( fromIndex, toIndex );
351 }
352
353 protected IndexOutOfBoundsException outOfBounds( int index )
354 {
355 return new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size() );
356 }
357
358 private class SubList extends AbstractImmutableList<E>
359 {
360 private final int fromIndex;
361 private final int toIndex;
362
363 private SubList( int fromIndex, int toIndex )
364 {
365 this.fromIndex = fromIndex;
366 this.toIndex = toIndex;
367 }
368
369 @Override
370 public E get( int index )
371 {
372 if ( index < 0 || index > size() )
373 {
374 throw outOfBounds( index );
375 }
376 return AbstractImmutableList.this.get( fromIndex + index );
377 }
378
379 @Override
380 public int size()
381 {
382 return toIndex - fromIndex;
383 }
384 }
385
386 private class Itr implements ListIterator<E>
387 {
388 int index;
389
390 private Itr( int index )
391 {
392 this.index = index;
393 }
394
395 @Override
396 public boolean hasNext()
397 {
398 return index < size();
399 }
400
401 @Override
402 public E next()
403 {
404 return get( index++ );
405 }
406
407 @Override
408 public boolean hasPrevious()
409 {
410 return index > 0;
411 }
412
413 @Override
414 public E previous()
415 {
416 return get( --index );
417 }
418
419 @Override
420 public int nextIndex()
421 {
422 return index;
423 }
424
425 @Override
426 public int previousIndex()
427 {
428 return index - 1;
429 }
430
431 @Override
432 public void remove()
433 {
434 throw uoe();
435 }
436
437 @Override
438 public void set( E e )
439 {
440 throw uoe();
441 }
442
443 @Override
444 public void add( E e )
445 {
446 throw uoe();
447 }
448 }
449 }
450
451 private static class ROProperties extends Properties
452 {
453 private ROProperties( Properties props )
454 {
455 super();
456 if ( props != null )
457 {
458
459 for ( Map.Entry<Object, Object> e : props.entrySet() )
460 {
461 super.put( e.getKey(), e.getValue() );
462 }
463 }
464 }
465
466 @Override
467 public Object put( Object key, Object value )
468 {
469 throw uoe();
470 }
471
472 @Override
473 public Object remove( Object key )
474 {
475 throw uoe();
476 }
477
478 @Override
479 public void putAll( Map<?, ?> t )
480 {
481 throw uoe();
482 }
483
484 @Override
485 public void clear()
486 {
487 throw uoe();
488 }
489
490 @Override
491 public void replaceAll( BiFunction<? super Object, ? super Object, ?> function )
492 {
493 throw uoe();
494 }
495
496 @Override
497 public Object putIfAbsent( Object key, Object value )
498 {
499 throw uoe();
500 }
501
502 @Override
503 public boolean remove( Object key, Object value )
504 {
505 throw uoe();
506 }
507
508 @Override
509 public boolean replace( Object key, Object oldValue, Object newValue )
510 {
511 throw uoe();
512 }
513
514 @Override
515 public Object replace( Object key, Object value )
516 {
517 throw uoe();
518 }
519
520 @Override
521 public Object computeIfAbsent( Object key, Function<? super Object, ?> mappingFunction )
522 {
523 throw uoe();
524 }
525
526 @Override
527 public Object computeIfPresent( Object key, BiFunction<? super Object, ? super Object, ?> remappingFunction )
528 {
529 throw uoe();
530 }
531
532 @Override
533 public Object compute( Object key, BiFunction<? super Object, ? super Object, ?> remappingFunction )
534 {
535 throw uoe();
536 }
537
538 @Override
539 public Object merge( Object key, Object value, BiFunction<? super Object, ? super Object, ?> remappingFunction )
540 {
541 throw uoe();
542 }
543 }
544
545 private static class Map1<K, V> extends AbstractImmutableMap<K, V>
546 {
547 private final Entry<K, V> entry;
548
549 private Map1( K key, V value )
550 {
551 this.entry = new SimpleImmutableEntry<>( key, value );
552 }
553
554 @Override
555 public Set<Entry<K, V>> entrySet()
556 {
557 return new AbstractImmutableSet<Entry<K, V>>()
558 {
559 @Override
560 public Iterator<Entry<K, V>> iterator()
561 {
562 return new Iterator<Entry<K, V>>()
563 {
564 int index = 0;
565 @Override
566 public boolean hasNext()
567 {
568 return index == 0;
569 }
570
571 @Override
572 public Entry<K, V> next()
573 {
574 if ( index++ == 0 )
575 {
576 return entry;
577 }
578 throw new NoSuchElementException();
579 }
580 };
581 }
582
583 @Override
584 public int size()
585 {
586 return 1;
587 }
588 };
589 }
590 }
591
592 private static class MapN<K, V> extends AbstractImmutableMap<K, V>
593 {
594 private final Object[] entries;
595
596 private MapN( Map<K, V> map )
597 {
598 entries = map != null ? map.entrySet().toArray() : new Object[0];
599 }
600
601 @Override
602 public Set<Entry<K, V>> entrySet()
603 {
604 return new AbstractImmutableSet<Entry<K, V>>()
605 {
606 @Override
607 public Iterator<Entry<K, V>> iterator()
608 {
609 return new Iterator<Entry<K, V>>()
610 {
611 int index = 0;
612 @Override
613 public boolean hasNext()
614 {
615 return index < entries.length;
616 }
617
618 @SuppressWarnings( "unchecked" )
619 @Override
620 public Entry<K, V> next()
621 {
622 if ( index < entries.length )
623 {
624 return ( Entry<K, V> ) entries[index++];
625 }
626 throw new NoSuchElementException();
627 }
628 };
629 }
630
631 @Override
632 public int size()
633 {
634 return entries.length;
635 }
636 };
637 }
638 }
639
640 private abstract static class AbstractImmutableMap<K, V>
641 extends AbstractMap<K, V>
642 implements Serializable
643 {
644 @Override
645 public void replaceAll( BiFunction<? super K, ? super V, ? extends V> function )
646 {
647 throw uoe();
648 }
649
650 @Override
651 public V putIfAbsent( K key, V value )
652 {
653 throw uoe();
654 }
655
656 @Override
657 public boolean remove( Object key, Object value )
658 {
659 throw uoe();
660 }
661
662 @Override
663 public boolean replace( K key, V oldValue, V newValue )
664 {
665 throw uoe();
666 }
667
668 @Override
669 public V replace( K key, V value )
670 {
671 throw uoe();
672 }
673
674 @Override
675 public V computeIfAbsent( K key, Function<? super K, ? extends V> mappingFunction )
676 {
677 throw uoe();
678 }
679
680 @Override
681 public V computeIfPresent( K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction )
682 {
683 throw uoe();
684 }
685
686 @Override
687 public V compute( K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction )
688 {
689 throw uoe();
690 }
691
692 @Override
693 public V merge( K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction )
694 {
695 throw uoe();
696 }
697 }
698
699 private abstract static class AbstractImmutableSet<E>
700 extends AbstractSet<E>
701 implements Serializable
702 {
703 @Override
704 public boolean removeAll( Collection<?> c )
705 {
706 throw uoe();
707 }
708
709 @Override
710 public boolean add( E e )
711 {
712 throw uoe();
713 }
714
715 @Override
716 public boolean remove( Object o )
717 {
718 throw uoe();
719 }
720
721 @Override
722 public boolean retainAll( Collection<?> c )
723 {
724 throw uoe();
725 }
726
727 @Override
728 public void clear()
729 {
730 throw uoe();
731 }
732
733 @Override
734 public boolean removeIf( Predicate<? super E> filter )
735 {
736 throw uoe();
737 }
738 }
739
740 private static UnsupportedOperationException uoe()
741 {
742 return new UnsupportedOperationException();
743 }
744
745 }