001: /*******************************************************************************
002: * Copyright (c) 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.Map;
018:
019: import org.eclipse.core.resources.IMarker;
020: import org.eclipse.core.runtime.CoreException;
021: import org.eclipse.swt.graphics.Image;
022: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerField;
023: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerItem;
024:
025: /**
026: * @since 3.2
027: *
028: */
029: public class MarkerGroup {
030:
031: class AttributeMapping extends EntryMapping {
032:
033: String attribute;
034:
035: String attributeValue;
036:
037: /**
038: * Create a mapping for an attribute with name attributeName and value
039: * value to the supplied entry.
040: *
041: * @param entry
042: * @param attributeName
043: * @param value
044: */
045: AttributeMapping(MarkerGroupingEntry entry,
046: String attributeName, String value) {
047: super (entry);
048: attribute = attributeName;
049: attributeValue = value;
050: }
051:
052: /*
053: * (non-Javadoc)
054: *
055: * @see org.eclipse.ui.views.markers.internal.FieldMarkerGroup.EntryMapping#hasAttributes()
056: */
057: public boolean hasAttributes() {
058: return true;
059: }
060:
061: /*
062: * (non-Javadoc)
063: *
064: * @see org.eclipse.ui.views.markers.internal.FieldMarkerGroup.EntryMapping#testAttribute(org.eclipse.ui.views.markers.internal.ConcreteMarker)
065: */
066: public MarkerGroupingEntry testAttribute(IMarker marker) {
067: Object value;
068:
069: if (!marker.exists())
070: return null;// If the marker was deleted during the update drop
071: // it
072:
073: try {
074: value = marker.getAttribute(attribute);
075: } catch (CoreException e) {
076: Util.log(e);
077: return null;
078: }
079:
080: if (value != null
081: && attributeValue.equals(value.toString())) {
082: return groupingEntry;
083: }
084: return null;
085: }
086: }
087:
088: class EntryMapping {
089: MarkerGroupingEntry groupingEntry;
090:
091: /**
092: * Create an entry mapping for the receiver.
093: *
094: * @param entry
095: */
096: EntryMapping(MarkerGroupingEntry entry) {
097: groupingEntry = entry;
098: }
099:
100: /**
101: * Return whether or not the receiver tests attributes.
102: *
103: * @return boolean
104: */
105: public boolean hasAttributes() {
106: return false;
107: }
108:
109: /**
110: * Test the attribute of the marker to find a grouping.
111: *
112: * @param marker
113: * @return MarkerGroupingEntry or <code>null</code> if there is not
114: * entry.
115: */
116: public MarkerGroupingEntry testAttribute(IMarker marker) {
117: return null;
118: }
119: }
120:
121: class FieldGroup implements IField {
122:
123: MarkerGroup markerGroup;
124:
125: private boolean showing;
126:
127: FieldGroup(MarkerGroup group) {
128: markerGroup = group;
129: }
130:
131: /*
132: * (non-Javadoc)
133: *
134: * @see org.eclipse.ui.views.markers.internal.IField#compare(java.lang.Object,
135: * java.lang.Object)
136: */
137: public int compare(Object obj1, Object obj2) {
138:
139: MarkerGroupingEntry entry1 = getMapping(((MarkerNode) obj1)
140: .getConcreteRepresentative());
141: MarkerGroupingEntry entry2 = getMapping(((MarkerNode) obj2)
142: .getConcreteRepresentative());
143: return entry2.getPriority() - entry1.getPriority();
144:
145: }
146:
147: /*
148: * (non-Javadoc)
149: *
150: * @see org.eclipse.ui.views.markers.internal.IField#getColumnHeaderImage()
151: */
152: public Image getColumnHeaderImage() {
153: return null;
154: }
155:
156: /*
157: * (non-Javadoc)
158: *
159: * @see org.eclipse.ui.views.markers.internal.IField#getColumnHeaderText()
160: */
161: public String getColumnHeaderText() {
162: return markerGroup.title;
163: }
164:
165: /*
166: * (non-Javadoc)
167: *
168: * @see org.eclipse.ui.views.markers.internal.IField#getDefaultDirection()
169: */
170: public int getDefaultDirection() {
171: return TableComparator.ASCENDING;
172: }
173:
174: /*
175: * (non-Javadoc)
176: *
177: * @see org.eclipse.ui.views.markers.internal.IField#getDescription()
178: */
179: public String getDescription() {
180: return markerGroup.title;
181: }
182:
183: /*
184: * (non-Javadoc)
185: *
186: * @see org.eclipse.ui.views.markers.internal.IField#getDescriptionImage()
187: */
188: public Image getDescriptionImage() {
189: return null;
190: }
191:
192: /*
193: * (non-Javadoc)
194: *
195: * @see org.eclipse.ui.views.markers.internal.IField#getImage(java.lang.Object)
196: */
197: public Image getImage(Object obj) {
198: return null;
199: }
200:
201: /*
202: * (non-Javadoc)
203: *
204: * @see org.eclipse.ui.views.markers.internal.IField#getPreferredWidth()
205: */
206: public int getPreferredWidth() {
207: return 75;
208: }
209:
210: /*
211: * (non-Javadoc)
212: *
213: * @see org.eclipse.ui.views.markers.internal.IField#getValue(java.lang.Object)
214: */
215: public String getValue(Object obj) {
216: MarkerNode node = (MarkerNode) obj;
217:
218: if (node.isConcrete()) {
219: MarkerGroupingEntry groupingEntry = markerGroup
220: .getMapping((ConcreteMarker) node);
221: return groupingEntry.getLabel();
222: }
223: return node.getDescription();
224: }
225:
226: /*
227: * (non-Javadoc)
228: *
229: * @see org.eclipse.ui.views.markers.internal.IField#isShowing()
230: */
231: public boolean isShowing() {
232: return this .showing;
233: }
234:
235: /*
236: * (non-Javadoc)
237: *
238: * @see org.eclipse.ui.views.markers.internal.IField#setShowing(boolean)
239: */
240: public void setShowing(boolean showing) {
241: this .showing = showing;
242:
243: }
244:
245: }
246:
247: /**
248: * GroupMarkerField is the MarkerField used for MarkerGroupungs
249: *
250: * @since 3.4
251: *
252: */
253: class GroupMarkerField extends MarkerField {
254:
255: MarkerGroup markerGroup;
256:
257: GroupMarkerField(MarkerGroup group) {
258: markerGroup = group;
259: }
260:
261: /*
262: * (non-Javadoc)
263: *
264: * @see org.eclipse.ui.internal.provisional.views.markers.api.MarkerField#getValue(org.eclipse.ui.internal.provisional.views.markers.api.MarkerItem)
265: */
266: public String getValue(MarkerItem item) {
267:
268: if (item.getMarker() != null) {
269:
270: try {
271: MarkerGroupingEntry groupingEntry = findGroupValue(
272: item.getMarker().getType(), item
273: .getMarker());
274: return groupingEntry.getLabel();
275: } catch (CoreException exception) {
276: return Util.EMPTY_STRING;
277: }
278: }
279: return item.getDescription();
280:
281: }
282:
283: /*
284: * (non-Javadoc)
285: *
286: * @see org.eclipse.ui.internal.provisional.views.markers.api.MarkerField#getColumnHeaderText()
287: */
288: public String getColumnHeaderText() {
289: return markerGroup.title;
290: }
291:
292: }
293:
294: private static MarkerGroupingEntry undefinedEntry = new MarkerGroupingEntry(
295: MarkerMessages.FieldCategory_Uncategorized, null, 0);
296:
297: protected IField field;
298:
299: private String id;
300:
301: protected MarkerField markerField;
302:
303: private String title;
304:
305: private Map typesToMappings = new HashMap();
306:
307: /**
308: * Create a new instance of the receiver called name with id identifier.
309: *
310: * @param name
311: * @param identifier
312: */
313: public MarkerGroup(String name, String identifier) {
314: title = name;
315: id = identifier;
316: createFields();
317: }
318:
319: /**
320: * Create the fields for the marker views.
321: */
322: protected void createFields() {
323: field = new FieldGroup(this );
324: markerField = new GroupMarkerField(this );
325: }
326:
327: /**
328: * Add the entry for the markerType.
329: *
330: * @param markerType
331: * @param entry
332: */
333: private void addEntry(String markerType, EntryMapping entry) {
334:
335: MarkerType[] allDerived = getMarkerTypes(markerType);
336:
337: for (int i = 0; i < allDerived.length; i++) {
338: Collection entries = new HashSet();
339: MarkerType type = allDerived[i];
340: if (typesToMappings.containsKey(type.getId())) {
341: entries = (Collection) typesToMappings.get(markerType);
342: } else {
343: entries = new HashSet();
344: }
345:
346: entries.add(entry);
347: typesToMappings.put(type.getId(), entries);
348: }
349:
350: }
351:
352: /**
353: * Find the group value. If it cannot be found in an attribute mapping then
354: * return null;
355: *
356: * @param concreteMarker
357: * @return String or <code>null</code>
358: */
359: private MarkerGroupingEntry findGroupValue(
360: ConcreteMarker concreteMarker) {
361:
362: String type = concreteMarker.getType();
363: IMarker marker = concreteMarker.getMarker();
364:
365: return findGroupValue(type, marker);
366:
367: }
368:
369: /**
370: * Find the group for the marker of the specified marker type.
371: *
372: * @param type
373: * @param marker
374: * @return MarkerGroupingEntry
375: */
376: public MarkerGroupingEntry findGroupValue(String type,
377: IMarker marker) {
378: if (typesToMappings.containsKey(type)) {
379: EntryMapping defaultMapping = null;
380: Iterator mappings = ((Collection) typesToMappings.get(type))
381: .iterator();
382: while (mappings.hasNext()) {
383: EntryMapping mapping = (EntryMapping) mappings.next();
384: if (mapping.hasAttributes()) {
385: MarkerGroupingEntry entry = mapping
386: .testAttribute(marker);
387: if (entry != null) {
388: return entry;
389: }
390: } else {
391: // If it has no attributes it is our default
392: defaultMapping = mapping;
393: }
394: }
395: if (defaultMapping != null) {
396: return defaultMapping.groupingEntry;
397: }
398:
399: }
400:
401: return undefinedEntry;
402: }
403:
404: /**
405: * Return the field for the receiver.
406: *
407: * @return {@link IField}
408: */
409: public IField getField() {
410: return field;
411: }
412:
413: /**
414: * Return the id of the receiver.
415: *
416: * @return String
417: */
418: public String getId() {
419: return id;
420: }
421:
422: /**
423: * Get the attribute mapping for the marker
424: *
425: * @param marker
426: * @return MarkerGroupingEntry
427: */
428: private MarkerGroupingEntry getMapping(ConcreteMarker marker) {
429:
430: if (marker.getGroup() == null) {
431: marker.setGroup(findGroupValue(marker));
432: }
433: return (MarkerGroupingEntry) marker.getGroup();
434: }
435:
436: /**
437: * Return the markerField for the receiver.
438: *
439: * @return MarkerField
440: */
441: public MarkerField getMarkerField() {
442: return markerField;
443: }
444:
445: /**
446: * Return the marker types that match and are subtypes of markerType.
447: *
448: * @param markerType
449: * @return MarkerType[]
450: */
451: private MarkerType[] getMarkerTypes(String markerType) {
452: MarkerTypesModel model = MarkerTypesModel.getInstance();
453: Collection types = new HashSet();
454:
455: MarkerType type = model.getType(markerType);
456: if (type != null) {
457: types.add(type);
458: MarkerType[] subs = type.getAllSubTypes();
459: for (int j = 0; j < subs.length; j++) {
460: types.add(subs[j]);
461: }
462: }
463:
464: if (types.isEmpty()) {
465: return new MarkerType[0];
466: }
467:
468: MarkerType[] typesArray = new MarkerType[types.size()];
469: types.toArray(typesArray);
470: return typesArray;
471: }
472:
473: /**
474: * Return the title for the receiver.
475: *
476: * @return String
477: */
478: public String getTitle() {
479: return title;
480: }
481:
482: /**
483: * Add an attributeMapping for the markerType.
484: *
485: * @param markerType
486: * @param attribute
487: * @param attributeValue
488: * @param entry
489: */
490: public void mapAttribute(String markerType, String attribute,
491: String attributeValue, MarkerGroupingEntry entry) {
492: addEntry(markerType, new AttributeMapping(entry, attribute,
493: attributeValue));
494:
495: }
496:
497: /**
498: * Remove the entry from all of the entries in the receiver.
499: *
500: * @param entry
501: */
502: public void remove(MarkerGroupingEntry entry) {
503: Iterator entries = typesToMappings.values().iterator();
504: Collection removeCollection = new ArrayList();
505: while (entries.hasNext()) {
506: Collection mappings = (Collection) entries.next();
507: Iterator mappingsIterator = mappings.iterator();
508: while (mappingsIterator.hasNext()) {
509: EntryMapping next = (EntryMapping) mappingsIterator
510: .next();
511: if (next.groupingEntry.equals(entry)) {
512: removeCollection.add(next);
513: }
514:
515: }
516: mappings.removeAll(removeCollection);
517: removeCollection.clear();
518: }
519:
520: }
521:
522: /**
523: * Set entry and the default entry for the supplied markerType.
524: *
525: * @param markerType
526: * @param entry
527: */
528:
529: public void setAsDefault(String markerType,
530: MarkerGroupingEntry entry) {
531: addEntry(markerType, new EntryMapping(entry));
532:
533: }
534:
535: }
|