1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.ui.viewsupport;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Stack;
18 import net.sourceforge.phpdt.core.ICompilationUnit;
19 import net.sourceforge.phpdt.core.IJavaElement;
21 import org.eclipse.core.resources.IResource;
22 import org.eclipse.jface.viewers.ContentViewer;
23 import org.eclipse.jface.viewers.ILabelProvider;
24 import org.eclipse.jface.viewers.IViewerLabelProvider;
25 import org.eclipse.jface.viewers.ViewerLabel;
26 import org.eclipse.swt.graphics.Image;
27 import org.eclipse.swt.widgets.Item;
30 * Helper class for updating error markers and other decorators that work on
31 * resources. Items are mapped to their element's underlying resource. Method
32 * <code>resourceChanged</code> updates all items that are affected from the
35 public class ResourceToItemsMapper {
37 private static final int NUMBER_LIST_REUSE = 10;
39 // map from resource to item
40 private HashMap fResourceToItem;
42 private Stack fReuseLists;
44 private ContentViewer fContentViewer;
46 public ResourceToItemsMapper(ContentViewer viewer) {
47 fResourceToItem = new HashMap();
48 fReuseLists = new Stack();
50 fContentViewer = viewer;
54 * Must be called from the UI thread.
56 public void resourceChanged(IResource changedResource) {
57 Object obj = fResourceToItem.get(changedResource);
60 } else if (obj instanceof Item) {
61 updateItem((Item) obj);
62 } else { // List of Items
63 List list = (List) obj;
64 for (int k = 0; k < list.size(); k++) {
65 updateItem((Item) list.get(k));
70 private void updateItem(Item item) {
71 if (!item.isDisposed()) { // defensive code
72 ILabelProvider lprovider = (ILabelProvider) fContentViewer
75 Object data = item.getData();
77 // If it is an IItemLabelProvider than short circuit: patch Tod (bug
79 if (lprovider instanceof IViewerLabelProvider) {
80 IViewerLabelProvider provider = (IViewerLabelProvider) lprovider;
82 ViewerLabel updateLabel = new ViewerLabel(item.getText(), item
84 provider.updateLabel(updateLabel, data);
86 if (updateLabel.hasNewImage()) {
87 item.setImage(updateLabel.getImage());
89 if (updateLabel.hasNewText()) {
90 item.setText(updateLabel.getText());
93 Image oldImage = item.getImage();
94 Image image = lprovider.getImage(data);
95 if (image != null && !image.equals(oldImage)) {
98 String oldText = item.getText();
99 String text = lprovider.getText(data);
100 if (text != null && !text.equals(oldText)) {
108 * Adds a new item to the map.
113 * The item used for the element
115 public void addToMap(Object element, Item item) {
116 IResource resource = getCorrespondingResource(element);
117 if (resource != null) {
118 Object existingMapping = fResourceToItem.get(resource);
119 if (existingMapping == null) {
120 fResourceToItem.put(resource, item);
121 } else if (existingMapping instanceof Item) {
122 if (existingMapping != item) {
123 List list = getNewList();
124 list.add(existingMapping);
126 fResourceToItem.put(resource, list);
129 List list = (List) existingMapping;
130 if (!list.contains(item)) {
138 * Removes an element from the map.
140 public void removeFromMap(Object element, Item item) {
141 IResource resource = getCorrespondingResource(element);
142 if (resource != null) {
143 Object existingMapping = fResourceToItem.get(resource);
144 if (existingMapping == null) {
146 } else if (existingMapping instanceof Item) {
147 fResourceToItem.remove(resource);
149 List list = (List) existingMapping;
151 if (list.isEmpty()) {
152 fResourceToItem.remove(list);
159 private List getNewList() {
160 if (!fReuseLists.isEmpty()) {
161 return (List) fReuseLists.pop();
163 return new ArrayList(2);
166 private void releaseList(List list) {
167 if (fReuseLists.size() < NUMBER_LIST_REUSE) {
168 fReuseLists.push(list);
175 public void clearMap() {
176 fResourceToItem.clear();
180 * Tests if the map is empty
182 public boolean isEmpty() {
183 return fResourceToItem.isEmpty();
187 * Method that decides which elements can have error markers Returns null if
188 * an element can not have error markers.
190 private static IResource getCorrespondingResource(Object element) {
191 if (element instanceof IJavaElement) {
192 IJavaElement elem = (IJavaElement) element;
193 if (!elem.isReadOnly()) { // only modifieable elements can get
195 IResource res = elem.getResource();
197 ICompilationUnit cu = (ICompilationUnit) elem
198 .getAncestor(IJavaElement.COMPILATION_UNIT);
200 // elements in compilation units are mapped to the
201 // underlying resource of the original cu
202 res = cu.getResource();
208 } else if (element instanceof IResource) {
209 return (IResource) element;