]> git.uio.no Git - ifi-stolz-refaktor.git/blame - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/viewsupport/ResourceToItemsMapper.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / viewsupport / ResourceToItemsMapper.java
CommitLineData
1b2798f6
EK
1/*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.jdt.internal.ui.viewsupport;
12
13import java.util.ArrayList;
14import java.util.HashMap;
15import java.util.List;
16import java.util.Stack;
17
18import org.eclipse.swt.widgets.Item;
19import org.eclipse.swt.widgets.Widget;
20
21import org.eclipse.core.resources.IResource;
22
23import org.eclipse.jdt.core.ICompilationUnit;
24import org.eclipse.jdt.core.IJavaElement;
25
26/**
27 * Helper class for updating error markers and other decorators that work on resources.
28 * Items are mapped to their element's underlying resource.
29 * Method <code>resourceChanged</code> updates all items that are affected from the changed
30 * elements.
31 */
32public class ResourceToItemsMapper {
33
34 public static interface IContentViewerAccessor {
35 public void doUpdateItem(Widget item);
36 }
37
38
39 private static final int NUMBER_LIST_REUSE= 10;
40
41 // map from IResource to Item or List<Item>
42 private HashMap<IResource, Object> fResourceToItem;
43 private Stack<List<Item>> fReuseLists;
44
45 private IContentViewerAccessor fContentViewerAccess;
46
47 public ResourceToItemsMapper(IContentViewerAccessor viewer) {
48 fResourceToItem= new HashMap<IResource, Object>();
49 fReuseLists= new Stack<List<Item>>();
50
51 fContentViewerAccess= viewer;
52 }
53
54 /**
55 * Must be called from the UI thread.
56 * @param changedResource Changed resource
57 */
58 public void resourceChanged(IResource changedResource) {
59 Object obj= fResourceToItem.get(changedResource);
60 if (obj == null) {
61 // not mapped
62 } else if (obj instanceof Item) {
63 updateItem((Item) obj);
64 } else { // List of Items
65 @SuppressWarnings("unchecked")
66 List<Item> list= (List<Item>) obj;
67 for (int k= 0; k < list.size(); k++) {
68 updateItem(list.get(k));
69 }
70 }
71 }
72
73 private void updateItem(Item item) {
74 if (!item.isDisposed()) {
75 fContentViewerAccess.doUpdateItem(item);
76 }
77 }
78
79 /**
80 * Adds a new item to the map.
81 * @param element Element to map
82 * @param item The item used for the element
83 */
84 public void addToMap(Object element, Item item) {
85 IResource resource= getCorrespondingResource(element);
86 if (resource != null) {
87 Object existingMapping= fResourceToItem.get(resource);
88 if (existingMapping == null) {
89 fResourceToItem.put(resource, item);
90 } else if (existingMapping instanceof Item) {
91 if (existingMapping != item) {
92 List<Item> list= getNewList();
93 list.add((Item) existingMapping);
94 list.add(item);
95 fResourceToItem.put(resource, list);
96 }
97 } else { // List
98 @SuppressWarnings("unchecked")
99 List<Item> list= (List<Item>) existingMapping;
100 if (!list.contains(item)) {
101 list.add(item);
102 }
103 }
104 }
105 }
106
107 /**
108 * Removes an element from the map.
109 * @param element The data element
110 * @param item The table or tree item
111 */
112 public void removeFromMap(Object element, Item item) {
113 IResource resource= getCorrespondingResource(element);
114 if (resource != null) {
115 Object existingMapping= fResourceToItem.get(resource);
116 if (existingMapping == null) {
117 return;
118 } else if (existingMapping instanceof Item) {
119 fResourceToItem.remove(resource);
120 } else { // List
121 @SuppressWarnings("unchecked")
122 List<Item> list= (List<Item>) existingMapping;
123 list.remove(item);
124 if (list.isEmpty()) {
125 fResourceToItem.remove(list);
126 releaseList(list);
127 }
128 }
129 }
130 }
131
132 private List<Item> getNewList() {
133 if (!fReuseLists.isEmpty()) {
134 return fReuseLists.pop();
135 }
136 return new ArrayList<Item>(2);
137 }
138
139 private void releaseList(List<Item> list) {
140 if (fReuseLists.size() < NUMBER_LIST_REUSE) {
141 fReuseLists.push(list);
142 }
143 }
144
145 /**
146 * Clears the map.
147 */
148 public void clearMap() {
149 fResourceToItem.clear();
150 }
151
152 /**
153 * Tests if the map is empty
154 * @return Returns if there are mappings
155 */
156 public boolean isEmpty() {
157 return fResourceToItem.isEmpty();
158 }
159
160 /**
161 * Method that decides which elements can have error markers
162 * Returns null if an element can not have error markers.
163 * @param element The input element
164 * @return Returns the corresponding resource or null
165 */
166 private static IResource getCorrespondingResource(Object element) {
167 if (element instanceof IJavaElement) {
168 IJavaElement elem= (IJavaElement) element;
169 IResource res= elem.getResource();
170 if (res == null) {
171 ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
172 if (cu != null) {
173 // elements in compilation units are mapped to the underlying resource of the original cu
174 res= cu.getResource();
175 }
176 }
177 return res;
178 } else if (element instanceof IResource) {
179 return (IResource) element;
180 }
181 return null;
182 }
183
184}