001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.views.markers.internal;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.HashMap;
015: import java.util.HashSet;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.Map;
019: import java.util.Set;
020:
021: import org.eclipse.core.resources.IMarker;
022: import org.eclipse.core.runtime.CoreException;
023: import org.eclipse.core.runtime.IConfigurationElement;
024: import org.eclipse.core.runtime.IExtension;
025: import org.eclipse.core.runtime.IExtensionPoint;
026: import org.eclipse.core.runtime.IStatus;
027: import org.eclipse.core.runtime.Platform;
028: import org.eclipse.core.runtime.Status;
029: import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
030: import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
031: import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
032: import org.eclipse.osgi.util.NLS;
033: import org.eclipse.ui.IPerspectiveDescriptor;
034: import org.eclipse.ui.PlatformUI;
035: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
036: import org.eclipse.ui.internal.provisional.views.markers.MarkerContentGenerator;
037: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerField;
038: import org.eclipse.ui.statushandlers.StatusManager;
039:
040: /**
041: * The ProblemFilterRegistryReader is the registry reader for declarative
042: * problem filters. See the org.eclipse.ui.markerSupport extension point.
043: *
044: * @since 3.2
045: *
046: */
047: public class MarkerSupportRegistry implements IExtensionChangeHandler {
048:
049: private static final String DESCRIPTION = "onDescription"; //$NON-NLS-1$
050:
051: private static final String ENABLED = "enabled"; //$NON-NLS-1$
052:
053: private static final Object ERROR = "ERROR";//$NON-NLS-1$
054:
055: static final String ID = "id"; //$NON-NLS-1$
056:
057: private static final Object INFO = "INFO";//$NON-NLS-1$
058:
059: private static final Object WARNING = "WARNING";//$NON-NLS-1$
060:
061: private static final String MARKER_ID = "markerId"; //$NON-NLS-1$
062:
063: /**
064: * The tag for the marker support extension
065: */
066: public static final String MARKER_SUPPORT = "markerSupport";//$NON-NLS-1$
067:
068: /**
069: * The name attribute.
070: */
071: public static final String NAME = "name"; //$NON-NLS-1$
072:
073: private static final Object ON_ANY = "ON_ANY"; //$NON-NLS-1$
074:
075: private static final Object ON_ANY_IN_SAME_CONTAINER = "ON_ANY_IN_SAME_CONTAINER";//$NON-NLS-1$
076:
077: private static final Object ON_SELECTED_AND_CHILDREN = "ON_SELECTED_AND_CHILDREN";//$NON-NLS-1$
078:
079: private static final Object ON_SELECTED_ONLY = "ON_SELECTED_ONLY"; //$NON-NLS-1$
080:
081: private static final Object PROBLEM_FILTER = "problemFilter";//$NON-NLS-1$
082:
083: private static final String SCOPE = "scope"; //$NON-NLS-1$
084:
085: private static final String SELECTED_TYPE = "selectedType"; //$NON-NLS-1$
086:
087: private static final String SEVERITY = "severity";//$NON-NLS-1$
088:
089: /**
090: * The key for marker type references.
091: */
092: public static final String MARKER_TYPE_REFERENCE = "markerTypeReference"; //$NON-NLS-1$
093:
094: private static final String MARKER_CATEGORY = "markerTypeCategory";//$NON-NLS-1$
095:
096: private static final String ATTRIBUTE_MAPPING = "markerAttributeMapping"; //$NON-NLS-1$
097:
098: private static final String MARKER_GROUPING = "markerGrouping"; //$NON-NLS-1$
099:
100: private static final String ATTRIBUTE = "attribute"; //$NON-NLS-1$
101:
102: private static final String VALUE = "value"; //$NON-NLS-1$
103:
104: private static final String LABEL = "label"; //$NON-NLS-1$
105:
106: private static final String MARKER_ATTRIBUTE_GROUPING = "markerAttributeGrouping";//$NON-NLS-1$
107:
108: private static final String DEFAULT_GROUPING_ENTRY = "defaultGroupingEntry";//$NON-NLS-1$
109:
110: private static final String MARKER_TYPE = "markerType";//$NON-NLS-1$
111:
112: private static final String PRIORITY = "priority"; //$NON-NLS-1$
113:
114: private static final String MARKER_GROUPING_ENTRY = "markerGroupingEntry"; //$NON-NLS-1$
115:
116: private static final Object SEVERITY_ID = "org.eclipse.ui.ide.severity";//$NON-NLS-1$
117:
118: private static final String MARKER_CONTENT_GENERATOR = "markerContentGenerator"; //$NON-NLS-1$
119:
120: private static final Object MARKER_FIELD = "markerField"; //$NON-NLS-1$
121:
122: private static final Object DEFAULT_PROBLEMS_GENERATOR_ID = "org.eclipse.ui.ide.problemsGenerator"; //$NON-NLS-1$
123:
124: private static final String ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
125:
126: private static MarkerSupportRegistry singleton;
127:
128: // Create a lock so that initialisation happens in one thread
129: private static Object creationLock = new Object();
130:
131: /**
132: * Get the instance of the registry.
133: *
134: * @return MarkerSupportRegistry
135: */
136: public static MarkerSupportRegistry getInstance() {
137: if (singleton == null) {
138: synchronized (creationLock) {
139: if (singleton == null) {
140: // thread
141: singleton = new MarkerSupportRegistry();
142: }
143: }
144: }
145: return singleton;
146: }
147:
148: private Map registeredFilters = new HashMap();
149:
150: private Map markerGroups = new HashMap();
151:
152: private Map markerGroupingEntries = new HashMap();
153:
154: private HashMap categories = new HashMap();
155:
156: private HashMap hierarchyOrders = new HashMap();
157:
158: private MarkerType rootType;
159:
160: private HashMap generators = new HashMap();
161:
162: private HashMap fields = new HashMap();
163:
164: /**
165: * Create a new instance of the receiver and read the registry.
166: */
167: private MarkerSupportRegistry() {
168: IExtensionTracker tracker = PlatformUI.getWorkbench()
169: .getExtensionTracker();
170: IExtensionPoint point = Platform.getExtensionRegistry()
171: .getExtensionPoint(IDEWorkbenchPlugin.IDE_WORKBENCH,
172: MARKER_SUPPORT);
173: if (point == null) {
174: return;
175: }
176: IExtension[] extensions = point.getExtensions();
177: // initial population
178: Map groupingEntries = new HashMap();
179: Set attributeMappings = new HashSet();
180: for (int i = 0; i < extensions.length; i++) {
181: IExtension extension = extensions[i];
182: processExtension(tracker, extension, groupingEntries,
183: attributeMappings);
184: }
185: postProcessExtensions(groupingEntries, attributeMappings);
186: tracker.registerHandler(this , ExtensionTracker
187: .createExtensionPointFilter(point));
188:
189: }
190:
191: /**
192: * Process the extension and register the result with the tracker. Fill the
193: * map of groupingEntries and attribueMappings processed for post
194: * processing.
195: *
196: * @param tracker
197: * @param extension
198: * @param groupingEntries
199: * Mapping of group names to the markerGroupingEntries registered
200: * for them
201: * @param attributeMappings
202: * the markerAttributeGroupings found
203: * @see #postProcessExtensions(Map, Collection)
204: */
205: private void processExtension(IExtensionTracker tracker,
206: IExtension extension, Map groupingEntries,
207: Collection attributeMappings) {
208: IConfigurationElement[] elements = extension
209: .getConfigurationElements();
210:
211: for (int j = 0; j < elements.length; j++) {
212: IConfigurationElement element = elements[j];
213: if (element.getName().equals(PROBLEM_FILTER)) {
214: ProblemFilter filter = newFilter(element);
215: registeredFilters.put(filter.getId(), filter);
216: tracker.registerObject(extension, filter,
217: IExtensionTracker.REF_STRONG);
218:
219: continue;
220: }
221: if (element.getName().equals(MARKER_GROUPING)) {
222:
223: String id = element.getAttribute(ID);
224: MarkerGroup group;
225: if (id.equals(Util.TYPE_MARKER_GROUPING_ID))
226: group = new TypeMarkerGroup(element
227: .getAttribute(LABEL));
228: else
229: group = new MarkerGroup(
230: element.getAttribute(LABEL), id);
231:
232: markerGroups.put(group.getId(), group);
233: tracker.registerObject(extension, group,
234: IExtensionTracker.REF_STRONG);
235: continue;
236: }
237:
238: if (element.getName().equals(MARKER_GROUPING_ENTRY)) {
239:
240: MarkerGroupingEntry entry = new MarkerGroupingEntry(
241: element.getAttribute(LABEL),
242: element.getAttribute(ID),
243: (Integer
244: .valueOf(element.getAttribute(PRIORITY))
245: .intValue()));
246:
247: String groupName = element
248: .getAttribute(MARKER_GROUPING);
249:
250: Collection entries;
251: if (groupingEntries.containsKey(groupName)) {
252: entries = (Collection) groupingEntries
253: .get(groupName);
254: } else {
255: entries = new HashSet();
256: }
257:
258: entries.add(entry);
259: groupingEntries.put(groupName, entries);
260:
261: tracker.registerObject(extension, entry,
262: IExtensionTracker.REF_STRONG);
263: continue;
264: }
265:
266: if (element.getName().equals(MARKER_ATTRIBUTE_GROUPING)) {
267:
268: AttributeMarkerGrouping grouping = new AttributeMarkerGrouping(
269: element.getAttribute(ATTRIBUTE), element
270: .getAttribute(MARKER_TYPE), element
271: .getAttribute(DEFAULT_GROUPING_ENTRY),
272: element);
273:
274: attributeMappings.add(grouping);
275:
276: tracker.registerObject(extension, grouping,
277: IExtensionTracker.REF_STRONG);
278: continue;
279: }
280:
281: if (element.getName().equals(MARKER_CATEGORY)) {
282:
283: String[] markerTypes = getMarkerTypes(element);
284: String categoryName = element.getAttribute(NAME);
285:
286: for (int i = 0; i < markerTypes.length; i++) {
287: categories.put(markerTypes[i], categoryName);
288:
289: }
290: tracker.registerObject(extension, categoryName,
291: IExtensionTracker.REF_STRONG);
292: continue;
293: }
294:
295: if (element.getName().equals(MARKER_CONTENT_GENERATOR)) {
296:
297: processContentGenerator(tracker, extension, element);
298: continue;
299: }
300:
301: if (element.getName().equals(MARKER_FIELD)) {
302:
303: processMarkerField(tracker, extension, element);
304: continue;
305: }
306:
307: }
308: }
309:
310: /**
311: * Create a table of MarkerFields
312: *
313: * @param tracker
314: * @param extension
315: * @param element
316: */
317: private void processMarkerField(IExtensionTracker tracker,
318: IExtension extension, IConfigurationElement element) {
319: MarkerField field = null;
320: try {
321: field = (MarkerField) IDEWorkbenchPlugin.createExtension(
322: element, ATTRIBUTE_CLASS);
323: field.setConfigurationElement(element);
324: } catch (CoreException e) {
325: StatusManager.getManager().handle(e.getStatus());
326: }
327:
328: if (field != null)
329: fields.put(element.getAttribute(ID), field);
330: }
331:
332: /**
333: * Process the content generator defined in the extension.
334: *
335: * @param tracker
336: * @param extension
337: * @param element
338: */
339: private void processContentGenerator(IExtensionTracker tracker,
340: IExtension extension, IConfigurationElement element) {
341: MarkerContentGenerator generator = new MarkerContentGenerator(
342: element);
343:
344: generators.put(generator.getId(), generator);
345:
346: tracker.registerObject(extension, generator,
347: IExtensionTracker.REF_STRONG);
348: }
349:
350: /**
351: * Process the cross references after all of the extensions have been read.
352: *
353: * @param groupingEntries
354: * Mapping of group names to the markerGroupingEntries registered
355: * for them
356: * @param attributeMappings
357: * the markerAttributeGroupings found
358: */
359: private void postProcessExtensions(Map groupingEntries,
360: Collection attributeMappings) {
361: processGroupingEntries(groupingEntries);
362: processAttributeMappings(attributeMappings);
363: postProcessContentGenerators();
364: }
365:
366: /**
367: * Set up the fields and filters
368: */
369: private void postProcessContentGenerators() {
370: Iterator generatorIterator = generators.values().iterator();
371: while (generatorIterator.hasNext()) {
372: MarkerContentGenerator generator = (MarkerContentGenerator) generatorIterator
373: .next();
374: generator.initializeFromConfigurationElement(this );
375: }
376:
377: }
378:
379: /**
380: * Process the grouping entries into thier required grouping entries.
381: *
382: * @param groupingEntries
383: */
384: private void processGroupingEntries(Map groupingEntries) {
385: Iterator entriesIterator = groupingEntries.keySet().iterator();
386: while (entriesIterator.hasNext()) {
387: String nextGroupId = (String) entriesIterator.next();
388: Iterator nextEntriesIterator = ((Collection) groupingEntries
389: .get(nextGroupId)).iterator();
390: if (markerGroups.containsKey(nextGroupId)) {
391: while (nextEntriesIterator.hasNext()) {
392: MarkerGroupingEntry next = (MarkerGroupingEntry) nextEntriesIterator
393: .next();
394: markerGroupingEntries.put(next.getId(), next);
395: next.setGroupingEntry((MarkerGroup) markerGroups
396: .get(nextGroupId));
397:
398: }
399: } else {
400: while (nextEntriesIterator.hasNext()) {
401: MarkerGroupingEntry next = (MarkerGroupingEntry) nextEntriesIterator
402: .next();
403: IDEWorkbenchPlugin
404: .log(NLS
405: .bind(
406: "markerGroupingEntry {0} defines invalid group {1}",//$NON-NLS-1$
407: new String[] {
408: next.getId(),
409: nextGroupId }));
410: }
411: }
412: }
413: }
414:
415: /**
416: * Process the attribute mappings into thier required grouping entries.
417: *
418: * @param attributeMappings
419: */
420: private void processAttributeMappings(Collection attributeMappings) {
421: Iterator mappingsIterator = attributeMappings.iterator();
422: while (mappingsIterator.hasNext()) {
423: AttributeMarkerGrouping next = (AttributeMarkerGrouping) mappingsIterator
424: .next();
425: String defaultEntryId = next.getDefaultGroupingEntry();
426: if (defaultEntryId != null) {
427: if (markerGroupingEntries.containsKey(defaultEntryId)) {
428: MarkerGroupingEntry entry = (MarkerGroupingEntry) markerGroupingEntries
429: .get(defaultEntryId);
430: entry.setAsDefault(next.getMarkerType());
431: } else {
432: IDEWorkbenchPlugin
433: .log(NLS
434: .bind(
435: "Reference to invalid markerGroupingEntry {0}",//$NON-NLS-1$
436: defaultEntryId));
437: }
438: }
439: IConfigurationElement[] mappings = next.getElement()
440: .getChildren(ATTRIBUTE_MAPPING);
441:
442: for (int i = 0; i < mappings.length; i++) {
443: String entryId = mappings[i]
444: .getAttribute(MARKER_GROUPING_ENTRY);
445:
446: if (markerGroupingEntries.containsKey(entryId)) {
447: MarkerGroupingEntry entry = (MarkerGroupingEntry) markerGroupingEntries
448: .get(entryId);
449: entry.mapAttribute(next.getMarkerType(), next
450: .getAttribute(), mappings[i]
451: .getAttribute(VALUE));
452: } else {
453: IDEWorkbenchPlugin
454: .log(NLS
455: .bind(
456: "Reference to invaild markerGroupingEntry {0}", //$NON-NLS-1$
457: defaultEntryId));
458: }
459:
460: }
461: }
462:
463: }
464:
465: /**
466: * Get the markerTypes defined in element.
467: *
468: * @param element
469: * @return String[]
470: */
471: private String[] getMarkerTypes(IConfigurationElement element) {
472: IConfigurationElement[] types = element
473: .getChildren(MARKER_TYPE_REFERENCE);
474: String[] ids = new String[types.length];
475: for (int i = 0; i < ids.length; i++) {
476: ids[i] = types[i].getAttribute(ID);
477: }
478: return ids;
479: }
480:
481: /*
482: * (non-Javadoc)
483: *
484: * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamichelpers.IExtensionTracker,
485: * org.eclipse.core.runtime.IExtension)
486: */
487: public void addExtension(IExtensionTracker tracker,
488: IExtension extension) {
489: Map groupingEntries = new HashMap();
490: Set attributeMappings = new HashSet();
491: processExtension(tracker, extension, groupingEntries,
492: attributeMappings);
493: postProcessExtensions(groupingEntries, attributeMappings);
494: }
495:
496: /**
497: * Get the collection of currently registered filters.
498: *
499: * @return Collection of ProblemFilter
500: */
501: public Collection getRegisteredFilters() {
502: Collection filteredFilters = new ArrayList();
503: Iterator registeredIterator = registeredFilters.values()
504: .iterator();
505: while (registeredIterator.hasNext()) {
506: ProblemFilter next = (ProblemFilter) registeredIterator
507: .next();
508: if (next.isFilteredOutByActivity()) {
509: continue;
510: }
511: filteredFilters.add(next);
512: }
513:
514: return filteredFilters;
515: }
516:
517: /**
518: * Get the constant for scope from element. Return -1 if there is no value.
519: *
520: * @param element
521: * @return int one of MarkerView#ON_ANY MarkerView#ON_SELECTED_ONLY
522: * MarkerView#ON_SELECTED_AND_CHILDREN
523: * MarkerView#ON_ANY_IN_SAME_CONTAINER
524: */
525: private int getScopeValue(IConfigurationElement element) {
526: String scope = element.getAttribute(SCOPE);
527: if (scope == null) {
528: return -1;
529: }
530: if (scope.equals(ON_ANY)) {
531: return MarkerFilter.ON_ANY;
532: }
533: if (scope.equals(ON_SELECTED_ONLY)) {
534: return MarkerFilter.ON_SELECTED_ONLY;
535: }
536: if (scope.equals(ON_SELECTED_AND_CHILDREN)) {
537: return MarkerFilter.ON_SELECTED_AND_CHILDREN;
538: }
539: if (scope.equals(ON_ANY_IN_SAME_CONTAINER)) {
540: return MarkerFilter.ON_ANY_IN_SAME_CONTAINER;
541: }
542:
543: return -1;
544: }
545:
546: /**
547: * Get the constant for scope from element. Return -1 if there is no value.
548: *
549: * @param element
550: * @return int one of MarkerView#ON_ANY MarkerView#ON_SELECTED_ONLY
551: * MarkerView#ON_SELECTED_AND_CHILDREN
552: * MarkerView#ON_ANY_IN_SAME_CONTAINER
553: */
554: private int getSeverityValue(IConfigurationElement element) {
555: String severity = element.getAttribute(SEVERITY);
556: if (severity == null) {
557: return -1;
558: }
559: if (severity.equals(INFO)) {
560: return ProblemFilter.SEVERITY_INFO;
561: }
562: if (severity.equals(WARNING)) {
563: return ProblemFilter.SEVERITY_WARNING;
564: }
565: if (severity.equals(ERROR)) {
566: return ProblemFilter.SEVERITY_ERROR;
567: }
568:
569: return -1;
570: }
571:
572: /**
573: * Read the problem filters in the receiver.
574: *
575: * @param element
576: * the filter element
577: * @return ProblemFilter
578: */
579: private ProblemFilter newFilter(IConfigurationElement element) {
580: ProblemFilter filter = new ProblemFilter(element
581: .getAttribute(NAME));
582:
583: filter.createContributionFrom(element);
584:
585: String enabledValue = element.getAttribute(ENABLED);
586: filter.setEnabled(enabledValue == null
587: || Boolean.valueOf(enabledValue).booleanValue());
588:
589: int scopeValue = getScopeValue(element);
590: if (scopeValue >= 0) {
591: filter.setOnResource(scopeValue);
592: }
593:
594: String description = element.getAttribute(DESCRIPTION);
595: if (description != null) {
596: boolean contains = true;
597: if (description.charAt(0) == '!') {// does not contain flag
598: description = description.substring(1, description
599: .length());
600: contains = false;
601: }
602: filter.setContains(contains);
603: filter.setDescription(description);
604: }
605:
606: int severityValue = getSeverityValue(element);
607: if (severityValue > 0) {
608: filter.setSelectBySeverity(true);
609: filter.setSeverity(severityValue);
610: } else {
611: filter.setSelectBySeverity(false);
612: }
613:
614: List selectedTypes = new ArrayList();
615: IConfigurationElement[] types = element
616: .getChildren(SELECTED_TYPE);
617: for (int j = 0; j < types.length; j++) {
618: String markerId = types[j].getAttribute(MARKER_ID);
619: if (markerId != null) {
620: MarkerType type = filter.getMarkerType(markerId);
621: if (type == null) {
622: IStatus status = new Status(
623: IStatus.WARNING,
624: IDEWorkbenchPlugin.IDE_WORKBENCH,
625: IStatus.WARNING,
626: MarkerMessages.ProblemFilterRegistry_nullType,
627: null);
628: IDEWorkbenchPlugin.getDefault().getLog()
629: .log(status);
630: } else {
631: selectedTypes.add(type);
632: }
633: }
634: }
635:
636: if (selectedTypes.size() > 0) {
637: // specified
638: filter.setSelectedTypes(selectedTypes);
639: }
640:
641: return filter;
642:
643: }
644:
645: /*
646: * (non-Javadoc)
647: *
648: * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension,
649: * java.lang.Object[])
650: */
651: public void removeExtension(IExtension extension, Object[] objects) {
652:
653: Collection removedGroups = new ArrayList();
654:
655: for (int i = 0; i < objects.length; i++) {
656: if (objects[i] instanceof ProblemFilter) {
657: registeredFilters.remove(objects[i]);
658: }
659:
660: if (objects[i] instanceof MarkerGroup) {
661: markerGroups.remove(((MarkerGroup) objects[i]).getId());
662: removedGroups.add(objects[i]);
663: }
664:
665: if (objects[i] instanceof MarkerGroupingEntry) {
666: MarkerGroupingEntry entry = (MarkerGroupingEntry) objects[i];
667: entry.getMarkerGroup().remove(entry);
668: markerGroupingEntries.remove(entry.getId());
669: }
670:
671: if (objects[i] instanceof String) {
672: removeValues(objects[i], categories);
673: }
674:
675: }
676:
677: Iterator entriesIterator = markerGroupingEntries.keySet()
678: .iterator();
679: Collection removedKeys = new ArrayList();
680: while (entriesIterator.hasNext()) {
681: String entryId = (String) entriesIterator.next();
682: MarkerGroupingEntry entry = (MarkerGroupingEntry) markerGroupingEntries
683: .get(entryId);
684: if (removedGroups.contains(entry.getMarkerGroup())) {
685: removedKeys.add(entryId);
686: }
687: }
688:
689: Iterator removedIterator = removedKeys.iterator();
690: while (removedIterator.hasNext()) {
691: markerGroupingEntries.remove(removedIterator.next());
692: }
693:
694: }
695:
696: /**
697: * Remove the value from all of the collection sets in cache. If the
698: * collection is empty remove the key as well.
699: *
700: * @param value
701: * @param cache
702: */
703: private void removeValues(Object value, HashMap cache) {
704: Collection keysToRemove = new ArrayList();
705: Iterator keys = cache.keySet().iterator();
706: while (keys.hasNext()) {
707: String key = (String) keys.next();
708: Object next = cache.get(key);
709: if (next instanceof Collection) {
710: Collection collection = (Collection) next;
711: if (collection.contains(value)) {
712: collection.remove(value);
713: if (collection.isEmpty()) {
714: keysToRemove.add(key);
715: }
716: break;
717: }
718: } else {
719: if (cache.get(key).equals(value)) {
720: keysToRemove.add(key);
721: }
722: }
723: }
724: Iterator keysToRemoveIterator = keysToRemove.iterator();
725: while (keysToRemoveIterator.hasNext()) {
726: cache.remove(keysToRemoveIterator.next());
727: }
728: }
729:
730: /**
731: * Get the category associated with marker. Return <code>null</code> if
732: * there are none.
733: *
734: * @param marker
735: * @return String or <code>null</code>
736: */
737: public String getCategory(IMarker marker) {
738: try {
739: return getCategory(marker.getType());
740: } catch (CoreException e) {
741: Util.log(e);
742: }
743: return null;
744: }
745:
746: /**
747: * Get the category associated with markerType. Return <code>null</code>
748: * if there are none.
749: *
750: * @param markerType
751: * @return String or <code>null</code>
752: */
753: public String getCategory(String markerType) {
754: if (categories.containsKey(markerType)) {
755: return (String) categories.get(markerType);
756: }
757: return null;
758: }
759:
760: /**
761: * Return the TableSorter that corresponds to type.
762: *
763: * @param type
764: * @return TableSorter
765: */
766: public TableComparator getSorterFor(String type) {
767: if (hierarchyOrders.containsKey(type)) {
768: return (TableComparator) hierarchyOrders.get(type);
769: }
770:
771: TableComparator sorter = findSorterInChildren(type,
772: getRootType());
773: if (sorter == null) {
774: return new TableComparator(new IField[0], new int[0],
775: new int[0]);
776: }
777: return sorter;
778: }
779:
780: /**
781: * Return the list of root marker types.
782: *
783: * @return List of MarkerType.
784: */
785: private MarkerType getRootType() {
786: if (rootType == null) {
787: rootType = (MarkerTypesModel.getInstance())
788: .getType(IMarker.PROBLEM);
789: }
790: return rootType;
791: }
792:
793: /**
794: * Find the best match sorter for typeName in the children. If it cannot be
795: * found then return <code>null</code>.
796: *
797: * @param typeName
798: * @param type
799: * @return TableSorter or <code>null</code>.
800: */
801: private TableComparator findSorterInChildren(String typeName,
802: MarkerType type) {
803:
804: MarkerType[] types = type.getAllSubTypes();
805: TableComparator defaultSorter = null;
806: if (hierarchyOrders.containsKey(type.getId())) {
807: defaultSorter = (TableComparator) hierarchyOrders.get(type
808: .getId());
809: }
810:
811: for (int i = 0; i < types.length; i++) {
812: MarkerType[] subtypes = types[i].getAllSubTypes();
813: for (int j = 0; j < subtypes.length; j++) {
814: TableComparator sorter = findSorterInChildren(typeName,
815: subtypes[j]);
816: if (sorter != null) {
817: return sorter;
818: }
819: }
820: }
821: return defaultSorter;
822:
823: }
824:
825: /**
826: * Return the FieldMarkerGroups in the receiver.
827: *
828: * @return Collection of {@link MarkerGroup}
829: */
830: public Collection getMarkerGroups() {
831: return markerGroups.values();
832: }
833:
834: /**
835: * Return the default groupfield.
836: *
837: * @return IField
838: */
839: IField getDefaultGroupField() {
840:
841: return ((MarkerGroup) markerGroups.get(SEVERITY_ID)).getField();
842: }
843:
844: /**
845: * Get the generator for id
846: *
847: * @param id
848: * @return MarkerContentGenerator or <code>null</code>.
849: */
850: public MarkerContentGenerator getGenerator(String id) {
851: if (id != null && generators.containsKey(id))
852: return (MarkerContentGenerator) generators.get(id);
853: return null;
854: }
855:
856: /**
857: * Return the generator for the supplied perspective.
858: *
859: * @param perspective
860: * @return {@link MarkerContentGenerator} or <code>null</code>.
861: */
862: public MarkerContentGenerator generatorFor(
863: IPerspectiveDescriptor perspective) {
864: String id = perspective.getId();
865: Iterator generatorIterator = generators.values().iterator();
866: while (generatorIterator.hasNext()) {
867: MarkerContentGenerator generator = (MarkerContentGenerator) generatorIterator
868: .next();
869: if (id.equals(generator.getDefaultPerspectiveId()))
870: return generator;
871: }
872: return getDefaultGenerator();
873: }
874:
875: /**
876: * Return the default content generator.
877: *
878: * @return MarkerContentGenerator
879: */
880: private MarkerContentGenerator getDefaultGenerator() {
881: return (MarkerContentGenerator) generators
882: .get(DEFAULT_PROBLEMS_GENERATOR_ID);
883: }
884:
885: /**
886: * Get the markerGroup associated with categoryName
887: *
888: * @param categoryName
889: * @return FieldMarkerGroup or <code>null</code>
890: */
891: public MarkerGroup getMarkerGroup(String categoryName) {
892: if (markerGroups.containsKey(categoryName))
893: return (MarkerGroup) markerGroups.get(categoryName);
894: return null;
895: }
896:
897: /**
898: * Return the field that maps to id.
899: *
900: * @param id
901: * @return {@link MarkerField} or <code>null</code>
902: */
903: public MarkerField getField(String id) {
904: if (fields.containsKey(id))
905: return (MarkerField) fields.get(id);
906: return null;
907: }
908:
909: /**
910: * Return an array of MarkerContentGenerator for the receiver.
911: *
912: * @return MarkerContentGenerator[]
913: */
914: public MarkerContentGenerator[] getGenerators() {
915: MarkerContentGenerator[] generatorArray = new MarkerContentGenerator[generators
916: .size()];
917: generators.values().toArray(generatorArray);
918: return generatorArray;
919: }
920:
921: }
|