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 resources.
31 * Items are mapped to their element's underlying resource.
32 * Method <code>resourceChanged</code> updates all items that are affected from the changed
35 public class ResourceToItemsMapper {
37 private static final int NUMBER_LIST_REUSE= 10;
39 // map from resource to item
40 private HashMap fResourceToItem;
41 private Stack fReuseLists;
43 private ContentViewer fContentViewer;
45 public ResourceToItemsMapper(ContentViewer viewer) {
46 fResourceToItem= new HashMap();
47 fReuseLists= new Stack();
49 fContentViewer= viewer;
53 * Must be called from the UI thread.
55 public void resourceChanged(IResource changedResource) {
56 Object obj= fResourceToItem.get(changedResource);
59 } else if (obj instanceof Item) {
60 updateItem((Item) obj);
61 } else { // List of Items
62 List list= (List) obj;
63 for (int k= 0; k < list.size(); k++) {
64 updateItem((Item) list.get(k));
69 private void updateItem(Item item) {
70 if (!item.isDisposed()) { // defensive code
71 ILabelProvider lprovider= (ILabelProvider) fContentViewer.getLabelProvider();
73 Object data= item.getData();
75 // If it is an IItemLabelProvider than short circuit: patch Tod (bug 55012)
76 if (lprovider instanceof IViewerLabelProvider) {
77 IViewerLabelProvider provider= (IViewerLabelProvider) lprovider;
79 ViewerLabel updateLabel= new ViewerLabel(item.getText(), item.getImage());
80 provider.updateLabel(updateLabel, data);
82 if (updateLabel.hasNewImage()) {
83 item.setImage(updateLabel.getImage());
85 if (updateLabel.hasNewText()) {
86 item.setText(updateLabel.getText());
89 Image oldImage= item.getImage();
90 Image image= lprovider.getImage(data);
91 if (image != null && !image.equals(oldImage)) {
94 String oldText= item.getText();
95 String text= lprovider.getText(data);
96 if (text != null && !text.equals(oldText)) {
104 * Adds a new item to the map.
105 * @param element Element to map
106 * @param item The item used for the element
108 public void addToMap(Object element, Item item) {
109 IResource resource= getCorrespondingResource(element);
110 if (resource != null) {
111 Object existingMapping= fResourceToItem.get(resource);
112 if (existingMapping == null) {
113 fResourceToItem.put(resource, item);
114 } else if (existingMapping instanceof Item) {
115 if (existingMapping != item) {
116 List list= getNewList();
117 list.add(existingMapping);
119 fResourceToItem.put(resource, list);
122 List list= (List) existingMapping;
123 if (!list.contains(item)) {
131 * Removes an element from the map.
133 public void removeFromMap(Object element, Item item) {
134 IResource resource= getCorrespondingResource(element);
135 if (resource != null) {
136 Object existingMapping= fResourceToItem.get(resource);
137 if (existingMapping == null) {
139 } else if (existingMapping instanceof Item) {
140 fResourceToItem.remove(resource);
142 List list= (List) existingMapping;
144 if (list.isEmpty()) {
145 fResourceToItem.remove(list);
152 private List getNewList() {
153 if (!fReuseLists.isEmpty()) {
154 return (List) fReuseLists.pop();
156 return new ArrayList(2);
159 private void releaseList(List list) {
160 if (fReuseLists.size() < NUMBER_LIST_REUSE) {
161 fReuseLists.push(list);
168 public void clearMap() {
169 fResourceToItem.clear();
173 * Tests if the map is empty
175 public boolean isEmpty() {
176 return fResourceToItem.isEmpty();
180 * Method that decides which elements can have error markers
181 * Returns null if an element can not have error markers.
183 private static IResource getCorrespondingResource(Object element) {
184 if (element instanceof IJavaElement) {
185 IJavaElement elem= (IJavaElement) element;
186 if (!elem.isReadOnly()) { // only modifieable elements can get error ticks
187 IResource res= elem.getResource();
189 ICompilationUnit cu= (ICompilationUnit) elem.getAncestor(IJavaElement.COMPILATION_UNIT);
191 // elements in compilation units are mapped to the underlying resource of the original cu
192 res= cu.getResource();
198 } else if (element instanceof IResource) {
199 return (IResource) element;