KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > views > markers > internal > MarkerAdapter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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  *******************************************************************************/

11 package org.eclipse.ui.views.markers.internal;
12
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.Comparator JavaDoc;
17
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.SubProgressMonitor;
21 import org.eclipse.jface.viewers.ViewerComparator;
22 import org.eclipse.osgi.util.NLS;
23
24 /**
25  * The MarkerAdapter is the adapter for the deferred update of markers.
26  *
27  * @since 3.1
28  *
29  */

30 public class MarkerAdapter {
31
32     class MarkerCategory extends MarkerNode {
33
34         MarkerAdapter markerAdapter;
35
36         int start;
37
38         int end;
39
40         private ConcreteMarker[] children;
41
42         private String JavaDoc name;
43
44         /**
45          * Create a new instance of the receiver that has the markers between
46          * startIndex and endIndex showing.
47          *
48          * @param adapter
49          * @param startIndex
50          * @param endIndex
51          */

52         MarkerCategory(MarkerAdapter adapter, int startIndex, int endIndex,
53                 String JavaDoc categoryName) {
54             markerAdapter = adapter;
55             start = startIndex;
56             end = endIndex;
57             name = categoryName;
58         }
59
60         /*
61          * (non-Javadoc)
62          *
63          * @see org.eclipse.ui.views.markers.internal.MarkerNode#getChildren()
64          */

65         public MarkerNode[] getChildren() {
66
67             if (children == null) {
68
69                 // Return nothing while a build is going on as this could be
70
// stale
71
if (building) {
72                     return Util.EMPTY_MARKER_ARRAY;
73                 }
74
75                 ConcreteMarker[] allMarkers = markerAdapter.lastMarkers
76                         .toArray();
77
78                 int totalSize = getDisplayedSize();
79                 children = new ConcreteMarker[totalSize];
80
81                 System.arraycopy(allMarkers, start, children, 0, totalSize);
82                 // Sort them locally now
83
view.getTableSorter().sort(view.getViewer(), children);
84
85                 for (int i = 0; i < children.length; i++) {
86                     children[i].setCategory(this);
87                 }
88             }
89             return children;
90
91         }
92
93         /**
94          * Return the number of errors being displayed.
95          *
96          * @return int
97          */

98         int getDisplayedSize() {
99             if (view.getMarkerLimit() > 0) {
100                 return Math.min(getTotalSize(), view.getMarkerLimit());
101             }
102             return getTotalSize();
103         }
104
105         /*
106          * (non-Javadoc)
107          *
108          * @see org.eclipse.ui.views.markers.internal.MarkerNode#getParent()
109          */

110         public MarkerNode getParent() {
111             return null;
112         }
113
114         /*
115          * (non-Javadoc)
116          *
117          * @see org.eclipse.ui.views.markers.internal.MarkerNode#getDescription()
118          */

119         public String JavaDoc getDescription() {
120
121             int size = end - start + 1;
122
123             if (size <= view.getMarkerLimit()) {
124
125                 if (size == 1)
126                     return NLS.bind(MarkerMessages.Category_One_Item_Label,
127                             new Object JavaDoc[] { name });
128
129                 return NLS.bind(MarkerMessages.Category_Label, new Object JavaDoc[] {
130                         name, String.valueOf(getDisplayedSize()) });
131             }
132             return NLS.bind(MarkerMessages.Category_Limit_Label, new Object JavaDoc[] {
133                     name, String.valueOf(getDisplayedSize()),
134                     String.valueOf(getTotalSize()) });
135         }
136
137         /**
138          * Get the total size of the receiver.
139          *
140          * @return int
141          */

142         private int getTotalSize() {
143             return end - start + 1;
144         }
145
146         /*
147          * (non-Javadoc)
148          *
149          * @see org.eclipse.ui.views.markers.internal.MarkerNode#isConcrete()
150          */

151         public boolean isConcrete() {
152             return false;
153         }
154
155         /*
156          * (non-Javadoc)
157          *
158          * @see org.eclipse.ui.views.markers.internal.MarkerNode#getConcreteRepresentative()
159          */

160         public ConcreteMarker getConcreteRepresentative() {
161             return markerAdapter.lastMarkers.getMarker(start);
162         }
163
164         /**
165          * Return the name of the receiver.
166          *
167          * @return String
168          */

169         public String JavaDoc getName() {
170             return name;
171         }
172     }
173
174     MarkerView view;
175
176     private MarkerList lastMarkers;
177
178     private MarkerCategory[] categories;
179
180     private boolean building = true;// Start with nothing until we have
181

182     // something
183

184     /**
185      * Create a new instance of the receiver.
186      *
187      * @param markerView
188      */

189     MarkerAdapter(MarkerView markerView) {
190         view = markerView;
191     }
192
193     /**
194      * Return the category sorter for the receiver. This should only be called
195      * in hierarchal mode or there will be a ClassCastException.
196      *
197      * @return CategorySorter
198      */

199     public CategoryComparator getCategorySorter() {
200         return (CategoryComparator) view.getViewer().getComparator();
201     }
202
203     /**
204      * Build all of the markers in the receiver.
205      *
206      * @param collector
207      * @param monitor
208      */

209     public void buildAllMarkers(IProgressMonitor monitor) {
210         building = true;
211         MarkerList newMarkers;
212         try {
213             int markerLimit = view.getMarkerLimit();
214             monitor.beginTask(MarkerMessages.MarkerView_19,
215                     markerLimit == -1 ? 60 : 100);
216             try {
217                 monitor.subTask(MarkerMessages.MarkerView_waiting_on_changes);
218
219                 if (monitor.isCanceled())
220                     return;
221
222                 monitor
223                         .subTask(MarkerMessages.MarkerView_searching_for_markers);
224                 SubProgressMonitor subMonitor = new SubProgressMonitor(monitor,
225                         10);
226                 MarkerFilter[] filters = view.getEnabledFilters();
227                 if (filters.length > 0)
228                     newMarkers = MarkerList.compute(filters, subMonitor, true);
229                 else
230                     // Grab any filter as a disabled filter gives all of them
231
newMarkers = MarkerList.compute(new MarkerFilter[] { view
232                             .getAllFilters()[0] }, subMonitor, true);
233
234                 if (monitor.isCanceled())
235                     return;
236
237                 view.refreshMarkerCounts(monitor);
238
239             } catch (CoreException e) {
240                 Util.log(e);
241                 newMarkers = new MarkerList();
242                 return;
243             }
244
245             if (monitor.isCanceled())
246                 return;
247
248             ViewerComparator sorter = view.getViewer().getComparator();
249
250             if (markerLimit == -1 || isShowingHierarchy()) {
251                 sorter.sort(view.getViewer(), newMarkers.toArray());
252             } else {
253
254                 monitor.subTask(MarkerMessages.MarkerView_18);
255                 SubProgressMonitor mon = new SubProgressMonitor(monitor, 40);
256
257                 newMarkers = SortUtil.getFirst(newMarkers, (Comparator JavaDoc) sorter,
258                         markerLimit, mon);
259                 if (monitor.isCanceled())
260                     return;
261                 
262                 sorter.sort(view.getViewer(), newMarkers.toArray());
263             }
264
265             if (newMarkers.getSize() == 0) {
266                 categories = new MarkerCategory[0];
267                 lastMarkers = newMarkers;
268                 monitor.done();
269                 return;
270             }
271
272             monitor.subTask(MarkerMessages.MarkerView_queueing_updates);
273
274             if (monitor.isCanceled())
275                 return;
276
277             if (isShowingHierarchy()) {
278                 MarkerCategory[] newCategories = buildHierarchy(newMarkers, 0,
279                         newMarkers.getSize() - 1, 0);
280                 if (monitor.isCanceled())
281                     return;
282                 categories = newCategories;
283             }
284
285             lastMarkers = newMarkers;
286             monitor.done();
287         } finally {
288             building = false;
289         }
290
291     }
292
293     /**
294      * Return whether or not a hierarchy is showing.
295      *
296      * @return boolean
297      */

298     boolean isShowingHierarchy() {
299
300         ViewerComparator sorter = view.getViewer().getComparator();
301         if (sorter instanceof CategoryComparator) {
302             return ((CategoryComparator) sorter).getCategoryField() != null;
303         }
304         return false;
305     }
306
307     /**
308      * Break the marker up into categories
309      *
310      * @param markers
311      * @param start
312      * the start index in the markers
313      * @param end
314      * the last index to check
315      * @param sortIndex -
316      * the parent of the field
317      * @param parent
318      * @return MarkerCategory[] or <code>null</code> if we are at the bottom
319      * of the tree
320      */

321     MarkerCategory[] buildHierarchy(MarkerList markers, int start, int end,
322             int sortIndex) {
323         CategoryComparator sorter = getCategorySorter();
324
325         if (sortIndex > 0) {
326             return null;// Are we out of categories?
327
}
328
329         Collection JavaDoc categories = new ArrayList JavaDoc();
330
331         Object JavaDoc previous = null;
332         int categoryStart = start;
333
334         Object JavaDoc[] elements = markers.getArray();
335
336         for (int i = start; i <= end; i++) {
337
338             if (previous != null) {
339                 // Are we at a category boundary?
340
if (sorter.compare(previous, elements[i], sortIndex, false) != 0) {
341                     categories.add(new MarkerCategory(this, categoryStart,
342                             i - 1, getNameForIndex(markers, categoryStart)));
343                     categoryStart = i;
344                 }
345             }
346             previous = elements[i];
347
348         }
349
350         if (end >= categoryStart) {
351             categories.add(new MarkerCategory(this, categoryStart, end,
352                     getNameForIndex(markers, categoryStart)));
353         }
354
355         // Flatten single categories
356
// if (categories.size() == 1) {
357
// return buildHierarchy(markers, start, end, sortIndex + 1, parent);
358
// }
359
MarkerCategory[] nodes = new MarkerCategory[categories.size()];
360         categories.toArray(nodes);
361         return nodes;
362
363     }
364
365     /**
366      * Get the name for the category from the marker at categoryStart in
367      * markers.
368      *
369      * @param markers
370      * @param categoryStart
371      * @return String
372      */

373     private String JavaDoc getNameForIndex(MarkerList markers, int categoryStart) {
374         return getCategorySorter().getCategoryField().getValue(
375                 markers.toArray()[categoryStart]);
376     }
377
378     /**
379      * Return the current list of markers.
380      *
381      * @return MarkerList
382      */

383     public MarkerList getCurrentMarkers() {
384         if (lastMarkers == null) {// First time?
385
view.scheduleMarkerUpdate(Util.SHORT_DELAY);
386             building = true;
387         }
388         if (building) {
389             return new MarkerList();
390         }
391         return lastMarkers;
392     }
393
394     /**
395      * Return the elements in the adapter.
396      *
397      * @param root
398      * @return Object[]
399      */

400     public Object JavaDoc[] getElements() {
401
402         if (lastMarkers == null) {// First time?
403
view.scheduleMarkerUpdate(Util.SHORT_DELAY);
404             building = true;
405         }
406         if (building) {
407             return Util.EMPTY_MARKER_ARRAY;
408         }
409         if (isShowingHierarchy() && categories != null) {
410             return categories;
411         }
412         return lastMarkers.toArray();
413     }
414
415     /**
416      * Return whether or not the receiver has markers without scheduling
417      * anything if it doesn't.
418      *
419      * @return boolean <code>true</code> if the markers have not been
420      * calculated.
421      */

422     public boolean hasNoMarkers() {
423         return lastMarkers == null;
424     }
425
426     /**
427      * Return the categories for the receiver.
428      *
429      * @return MarkerCategory[] or <code>null</code> if there are no
430      * categories.
431      */

432     public MarkerCategory[] getCategories() {
433         if (building) {
434             return null;
435         }
436         return categories;
437     }
438
439     /**
440      * Return whether or not the receiver is building.
441      * @return boolean
442      */

443     boolean isBuilding() {
444         return building;
445     }
446
447 }
448
Popular Tags