1
16 package org.modelmapper.internal;
17
18 import java.util.AbstractList;
19 import java.util.Collection;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import net.jodah.typetools.TypeResolver;
24 import org.modelmapper.internal.util.Assert;
25 import org.modelmapper.internal.util.CopyOnWriteLinkedHashMap;
26
27
32 public class TypeResolvingList<T> extends AbstractList<T> {
33 private final Map<T, Class<?>> elements = new CopyOnWriteLinkedHashMap<T, Class<?>>();
34 private final Class<? super T> valueAccessorType;
35
36 public TypeResolvingList(Class<? super T> valueAccessorType) {
37 this.valueAccessorType = valueAccessorType;
38 }
39
40 @Override
41 public void add(int index, T element) {
42 addElement(element);
43 }
44
45 @Override
46 public int size() {
47 return elements.size();
48 }
49
50 @Override
51 public boolean add(T element) {
52 return addElement(element);
53 }
54
55 @Override
56 public T get(int index) {
57 Iterator<T> iterator = elements.keySet().iterator();
58 for (int i = 0; i < index; i++) {
59 iterator.next();
60 }
61 return iterator.next();
62 }
63
64 @Override
65 public boolean addAll(Collection<? extends T> c) {
66 boolean changed = false;
67 for (T e : c) {
68 changed = addElement(e) || changed;
69 }
70
71 return changed;
72 }
73
74 @Override
75 public boolean addAll(int index, Collection<? extends T> c) {
76 throw new UnsupportedOperationException();
77 }
78
79 @Override
80 public void clear() {
81 elements.clear();
82 }
83
84 @Override
85 public T remove(int index) {
86 T element = get(index);
87 elements.remove(element);
88 return element;
89 }
90
91 @Override
92 public boolean remove(Object o) {
93 elements.remove(o);
94 return true;
95 }
96
97 @Override
98 public boolean removeAll(Collection<?> c) {
99 for (Object e : c) {
100 @SuppressWarnings("unchecked")
101 T t = (T) e;
102 elements.remove(t);
103 }
104 return true;
105 }
106
107 @Override
108 public boolean retainAll(Collection<?> c) {
109 throw new UnsupportedOperationException();
110 }
111
112 @Override
113 public T set(int index, T element) {
114 throw new UnsupportedOperationException();
115 }
116
117 @Override
118 public List<T> subList(int fromIndex, int toIndex) {
119 throw new UnsupportedOperationException();
120 }
121
122 private boolean addElement(T element) {
123 Assert.notNull(element, "element");
124 Class<?> typeArgument = TypeResolver.resolveRawArgument(valueAccessorType, element.getClass());
125 if (typeArgument == null) {
126 throw new IllegalArgumentException("Must declare source type argument <T> for the " + valueAccessorType.getSimpleName());
127 }
128 elements.put(element, typeArgument);
129 return true;
130 }
131
132 public T first(Class<?> type) {
133 for (Map.Entry<T, Class<?>> entry : elements.entrySet())
134 if (entry.getValue().isAssignableFrom(type))
135 return entry.getKey();
136 return null;
137 }
138 }
139