PageRenderTime 25ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/core/src/main/java/jenkins/model/lazy/BuildReferenceMapAdapter.java

http://github.com/jenkinsci/jenkins
Java | 403 lines | 313 code | 72 blank | 18 comment | 17 complexity | f7bc8b17c3297712098806252e7e354e MD5 | raw file
  1. package jenkins.model.lazy;
  2. import edu.umd.cs.findbugs.annotations.Nullable;
  3. import hudson.util.AdaptedIterator;
  4. import hudson.util.Iterators;
  5. import java.lang.reflect.Array;
  6. import java.util.AbstractMap;
  7. import java.util.ArrayList;
  8. import java.util.Collection;
  9. import java.util.Comparator;
  10. import java.util.Iterator;
  11. import java.util.LinkedHashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. import java.util.Set;
  15. import java.util.SortedMap;
  16. /**
  17. * Take {@code SortedMap<Integer,BuildReference<R>>} and make it look like {@code SortedMap<Integer,R>}.
  18. *
  19. * When {@link BuildReference} lost the build object, we'll use {@link AbstractLazyLoadRunMap#getById(String)}
  20. * to obtain one.
  21. *
  22. * @author Kohsuke Kawaguchi
  23. */
  24. class BuildReferenceMapAdapter<R> implements SortedMap<Integer,R> {
  25. private final AbstractLazyLoadRunMap<R> loader;
  26. private final SortedMap<Integer,BuildReference<R>> core;
  27. BuildReferenceMapAdapter(AbstractLazyLoadRunMap<R> loader, SortedMap<Integer, BuildReference<R>> core) {
  28. this.loader = loader;
  29. this.core = core;
  30. }
  31. private R unwrap(@Nullable BuildReference<R> ref) {
  32. if (ref==null) return null;
  33. R v = ref.get();
  34. if (v==null)
  35. v = loader.getById(ref.id);
  36. return v;
  37. }
  38. private BuildReference<R> wrap(@Nullable R value) {
  39. if (value==null) return null;
  40. return loader.createReference(value);
  41. }
  42. @Override
  43. public Comparator<? super Integer> comparator() {
  44. return core.comparator();
  45. }
  46. @Override
  47. public SortedMap<Integer, R> subMap(Integer fromKey, Integer toKey) {
  48. return new BuildReferenceMapAdapter<>(loader, core.subMap(fromKey, toKey));
  49. }
  50. @Override
  51. public SortedMap<Integer, R> headMap(Integer toKey) {
  52. return new BuildReferenceMapAdapter<>(loader, core.headMap(toKey));
  53. }
  54. @Override
  55. public SortedMap<Integer, R> tailMap(Integer fromKey) {
  56. return new BuildReferenceMapAdapter<>(loader, core.tailMap(fromKey));
  57. }
  58. @Override
  59. public Integer firstKey() {
  60. return core.firstKey();
  61. }
  62. @Override
  63. public Integer lastKey() {
  64. return core.lastKey();
  65. }
  66. @Override
  67. public Set<Integer> keySet() {
  68. return core.keySet();
  69. }
  70. @Override
  71. public Collection<R> values() {
  72. return new CollectionAdapter(core.values());
  73. }
  74. @Override
  75. public Set<Entry<Integer,R>> entrySet() {
  76. return new SetAdapter(core.entrySet());
  77. }
  78. @Override
  79. public int size() {
  80. return core.size();
  81. }
  82. @Override
  83. public boolean isEmpty() {
  84. return core.isEmpty();
  85. }
  86. @Override
  87. public boolean containsKey(Object key) {
  88. return core.containsKey(key);
  89. }
  90. @Override
  91. public boolean containsValue(Object value) {
  92. return core.containsValue(value); // TODO should this be core.containsValue(wrap(value))?
  93. }
  94. @Override
  95. public R get(Object key) {
  96. return unwrap(core.get(key));
  97. }
  98. @Override
  99. public R put(Integer key, R value) {
  100. return unwrap(core.put(key, wrap(value)));
  101. }
  102. @Override
  103. public R remove(Object key) {
  104. return unwrap(core.remove(key));
  105. }
  106. @Override
  107. public void putAll(Map<? extends Integer, ? extends R> m) {
  108. for (Entry<? extends Integer, ? extends R> e : m.entrySet())
  109. put(e.getKey(), e.getValue());
  110. }
  111. @Override
  112. public void clear() {
  113. core.clear();
  114. }
  115. @Override
  116. public boolean equals(Object o) {
  117. return core.equals(o); // TODO this is wrong
  118. }
  119. @Override
  120. public int hashCode() {
  121. return core.hashCode();
  122. }
  123. @Override public String toString() {
  124. return new LinkedHashMap<>(this).toString();
  125. }
  126. private class CollectionAdapter implements Collection<R> {
  127. private final Collection<BuildReference<R>> core;
  128. private CollectionAdapter(Collection<BuildReference<R>> core) {
  129. this.core = core;
  130. }
  131. @Override
  132. public int size() {
  133. return core.size();
  134. }
  135. @Override
  136. public boolean isEmpty() {
  137. return core.isEmpty();
  138. }
  139. @Override
  140. public boolean contains(Object o) {
  141. // TODO: to properly pass this onto core, we need to wrap o into BuildReference but also needs to figure out ID.
  142. throw new UnsupportedOperationException();
  143. }
  144. @Override
  145. public Iterator<R> iterator() {
  146. // silently drop null, as if we didn't have them in this collection in the first place
  147. // this shouldn't be indistinguishable from concurrent modifications to the collection
  148. return Iterators.removeNull(new AdaptedIterator<BuildReference<R>,R>(core.iterator()) {
  149. @Override
  150. protected R adapt(BuildReference<R> ref) {
  151. return unwrap(ref);
  152. }
  153. });
  154. }
  155. @Override
  156. public Object[] toArray() {
  157. List<Object> list = new ArrayList<>(this);
  158. return list.toArray();
  159. }
  160. @Override
  161. public <T> T[] toArray(T[] a) {
  162. int size = size();
  163. T[] r = a;
  164. if (r.length>size)
  165. r = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
  166. Iterator<R> itr = iterator();
  167. int i=0;
  168. while (itr.hasNext()) {
  169. r[i++] = (T)itr.next();
  170. }
  171. return r;
  172. }
  173. @Override
  174. public boolean add(R value) {
  175. return core.add(wrap(value));
  176. }
  177. @Override
  178. public boolean remove(Object o) {
  179. // return core.remove(o);
  180. // TODO: to properly pass this onto core, we need to wrap o into BuildReference but also needs to figure out ID.
  181. throw new UnsupportedOperationException();
  182. }
  183. @Override
  184. public boolean containsAll(Collection<?> c) {
  185. for (Object o : c) {
  186. if (!contains(o))
  187. return false;
  188. }
  189. return true;
  190. }
  191. @Override
  192. public boolean addAll(Collection<? extends R> c) {
  193. boolean b=false;
  194. for (R r : c) {
  195. b |= add(r);
  196. }
  197. return b;
  198. }
  199. @Override
  200. public boolean removeAll(Collection<?> c) {
  201. boolean b=false;
  202. for (Object o : c) {
  203. b|=remove(o);
  204. }
  205. return b;
  206. }
  207. @Override
  208. public boolean retainAll(Collection<?> c) {
  209. // TODO: to properly pass this onto core, we need to wrap o into BuildReference but also needs to figure out ID.
  210. throw new UnsupportedOperationException();
  211. }
  212. @Override
  213. public void clear() {
  214. core.clear();
  215. }
  216. @Override
  217. public boolean equals(Object o) {
  218. return core.equals(o);
  219. }
  220. @Override
  221. public int hashCode() {
  222. return core.hashCode();
  223. }
  224. }
  225. private class SetAdapter implements Set<Entry<Integer, R>> {
  226. private final Set<Entry<Integer, BuildReference<R>>> core;
  227. private SetAdapter(Set<Entry<Integer, BuildReference<R>>> core) {
  228. this.core = core;
  229. }
  230. @Override
  231. public int size() {
  232. return core.size();
  233. }
  234. @Override
  235. public boolean isEmpty() {
  236. return core.isEmpty();
  237. }
  238. @Override
  239. public boolean contains(Object o) {
  240. // TODO: to properly pass this onto core, we need to wrap o into BuildReference but also needs to figure out ID.
  241. throw new UnsupportedOperationException();
  242. }
  243. @Override
  244. public Iterator<Entry<Integer, R>> iterator() {
  245. return Iterators.removeNull(new AdaptedIterator<Entry<Integer,BuildReference<R>>,Entry<Integer, R>>(core.iterator()) {
  246. @Override
  247. protected Entry<Integer, R> adapt(Entry<Integer, BuildReference<R>> e) {
  248. return _unwrap(e);
  249. }
  250. });
  251. }
  252. @Override
  253. public Object[] toArray() {
  254. List<Object> list = new ArrayList<>(this);
  255. return list.toArray();
  256. }
  257. @Override
  258. public <T> T[] toArray(T[] a) {
  259. int size = size();
  260. T[] r = a;
  261. if (r.length>size)
  262. r = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
  263. Iterator<Entry<Integer, R>> itr = iterator();
  264. int i=0;
  265. while (itr.hasNext()) {
  266. r[i++] = (T)itr.next();
  267. }
  268. return r;
  269. }
  270. @Override
  271. public boolean add(Entry<Integer, R> value) {
  272. return core.add(_wrap(value));
  273. }
  274. @Override
  275. public boolean remove(Object o) {
  276. // return core.remove(o);
  277. // TODO: to properly pass this onto core, we need to wrap o into BuildReference but also needs to figure out ID.
  278. throw new UnsupportedOperationException();
  279. }
  280. @Override
  281. public boolean containsAll(Collection<?> c) {
  282. for (Object o : c) {
  283. if (!contains(o))
  284. return false;
  285. }
  286. return true;
  287. }
  288. @Override
  289. public boolean addAll(Collection<? extends Entry<Integer,R>> c) {
  290. boolean b=false;
  291. for (Entry<Integer,R> r : c) {
  292. b |= add(r);
  293. }
  294. return b;
  295. }
  296. @Override
  297. public boolean removeAll(Collection<?> c) {
  298. boolean b=false;
  299. for (Object o : c) {
  300. b|=remove(o);
  301. }
  302. return b;
  303. }
  304. @Override
  305. public boolean retainAll(Collection<?> c) {
  306. // TODO: to properly pass this onto core, we need to wrap o into BuildReference but also needs to figure out ID.
  307. throw new UnsupportedOperationException();
  308. }
  309. @Override
  310. public void clear() {
  311. core.clear();
  312. }
  313. @Override
  314. public boolean equals(Object o) {
  315. return core.equals(o);
  316. }
  317. @Override
  318. public int hashCode() {
  319. return core.hashCode();
  320. }
  321. private Entry<Integer,BuildReference<R>> _wrap(Entry<Integer,R> e) {
  322. return new AbstractMap.SimpleEntry<>(e.getKey(),wrap(e.getValue()));
  323. }
  324. private Entry<Integer, R> _unwrap(Entry<Integer, BuildReference<R>> e) {
  325. R v = unwrap(e.getValue());
  326. if (v==null)
  327. return null;
  328. return new AbstractMap.SimpleEntry<>(e.getKey(), v);
  329. }
  330. }
  331. }