001: /*******************************************************************************
002: * Copyright (c) 2007 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.internal.provisional.views.markers;
011:
012: import java.io.IOException;
013: import java.io.StringReader;
014: import java.io.StringWriter;
015: import java.util.ArrayList;
016: import java.util.Arrays;
017: import java.util.Collection;
018: import java.util.HashSet;
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import org.eclipse.core.resources.IMarker;
023: import org.eclipse.core.resources.IResource;
024: import org.eclipse.core.resources.ResourcesPlugin;
025: import org.eclipse.core.resources.mapping.ResourceMapping;
026: import org.eclipse.core.resources.mapping.ResourceMappingContext;
027: import org.eclipse.core.resources.mapping.ResourceTraversal;
028: import org.eclipse.core.runtime.CoreException;
029: import org.eclipse.core.runtime.IAdaptable;
030: import org.eclipse.core.runtime.IConfigurationElement;
031: import org.eclipse.core.runtime.IProgressMonitor;
032: import org.eclipse.core.runtime.NullProgressMonitor;
033: import org.eclipse.core.runtime.SubProgressMonitor;
034: import org.eclipse.jface.preference.IPreferenceStore;
035: import org.eclipse.ui.IMemento;
036: import org.eclipse.ui.IWorkingSet;
037: import org.eclipse.ui.WorkbenchException;
038: import org.eclipse.ui.XMLMemento;
039: import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
040: import org.eclipse.ui.internal.provisional.views.markers.api.FilterConfigurationArea;
041: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerField;
042: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerItem;
043: import org.eclipse.ui.internal.provisional.views.markers.api.MarkerSupportConstants;
044: import org.eclipse.ui.statushandlers.StatusManager;
045: import org.eclipse.ui.views.markers.internal.MarkerGroup;
046: import org.eclipse.ui.views.markers.internal.MarkerMessages;
047: import org.eclipse.ui.views.markers.internal.MarkerSupportRegistry;
048: import org.eclipse.ui.views.markers.internal.MarkerType;
049: import org.eclipse.ui.views.markers.internal.MarkerTypesModel;
050: import org.eclipse.ui.views.markers.internal.Util;
051:
052: /**
053: * MarkerContentGenerator is the representation of the markerContentGenerator
054: * extension point.
055: *
056: * @since 3.4
057: *
058: */
059: public class MarkerContentGenerator {
060:
061: private static final String ATTRIBUTE_DEFAULT_FOR_PERSPECTIVE = "defaultForPerspective"; //$NON-NLS-1$
062: private static final String ATTRIBUTE_DEFAULT_MARKER_GROUPING = "defaultMarkerGrouping"; //$NON-NLS-1$
063: private static final String ATTRIBUTE_VISIBLE = "visible"; //$NON-NLS-1$
064: static final Object CACHE_UPDATE_FAMILY = new Object();
065: private static final String ELEMENT_MARKER_FIELD_FILTER_GROUP = "markerFieldFilterGrouping"; //$NON-NLS-1$;
066: private static final IResource[] EMPTY_RESOURCE_ARRAY = new IResource[0];
067: private static final String MARKER_FIELD_REFERENCE = "markerFieldReference"; //$NON-NLS-1$
068: private static final String TAG_FILTERS_SECTION = "filterGroups"; //$NON-NLS-1$
069: private static final String TAG_GROUP_ENTRY = "filterGroup"; //$NON-NLS-1$
070: private static final Object VALUE_FALSE = "false"; //$NON-NLS-1$
071: private MarkerField[] allFields;
072: private MarkerGroup categoryGroup;
073: private IConfigurationElement configurationElement;
074: private Collection enabledFilters;
075: private Collection filters;
076: private IResource[] focusResources = MarkerSupportInternalUtilities.EMPTY_RESOURCE_ARRAY;
077: private Collection markerTypes;
078: private MarkerField[] visibleFields;
079:
080: private IWorkingSet workingSet;
081:
082: /**
083: * Create a new MarkerContentGenerator
084: *
085: * @param element
086: */
087: public MarkerContentGenerator(IConfigurationElement element) {
088: configurationElement = element;
089: }
090:
091: /**
092: * Add the resources in resourceMapping to the resourceCollection
093: *
094: * @param resourceCollection
095: * @param resourceMapping
096: */
097: private void addResources(Collection resourceCollection,
098: ResourceMapping resourceMapping) {
099:
100: try {
101: ResourceTraversal[] traversals = resourceMapping
102: .getTraversals(
103: ResourceMappingContext.LOCAL_CONTEXT,
104: new NullProgressMonitor());
105: for (int i = 0; i < traversals.length; i++) {
106: ResourceTraversal traversal = traversals[i];
107: IResource[] result = traversal.getResources();
108: for (int j = 0; j < result.length; j++) {
109: resourceCollection.add(result[j]);
110: }
111: }
112: } catch (CoreException e) {
113: StatusManager.getManager().handle(e.getStatus());
114: }
115:
116: }
117:
118: /**
119: * Compute all of the markers for the receiver's type.
120: *
121: * @param subMonitor
122: * @return MarkerEntry
123: */
124: private Collection computeAllMarkers(SubProgressMonitor subMonitor) {
125: Collection allMarkers = new HashSet();
126: findMarkers(allMarkers, new IResource[] { ResourcesPlugin
127: .getWorkspace().getRoot() }, null,
128: IResource.DEPTH_INFINITE, subMonitor);
129: return allMarkers;
130: }
131:
132: /**
133: * Compute the marker for the supplied filter and add to return markers.
134: *
135: * @param returnMarkers
136: * @param subMonitor
137: * @param filterGroup
138: */
139: private void computeMarkers(Collection returnMarkers,
140: SubProgressMonitor subMonitor,
141: MarkerFieldFilterGroup filterGroup) {
142:
143: int filterType = filterGroup.getScope();
144:
145: switch (filterType) {
146: case MarkerFieldFilterGroup.ON_ANY: {
147: findMarkers(returnMarkers,
148: new IResource[] { ResourcesPlugin.getWorkspace()
149: .getRoot() }, filterGroup,
150: IResource.DEPTH_INFINITE, subMonitor);
151: break;
152: }
153: case MarkerFieldFilterGroup.ON_SELECTED_ONLY: {
154: findMarkers(returnMarkers, focusResources, filterGroup,
155: IResource.DEPTH_ZERO, subMonitor);
156: break;
157: }
158: case MarkerFieldFilterGroup.ON_SELECTED_AND_CHILDREN: {
159: findMarkers(returnMarkers, focusResources, filterGroup,
160: IResource.DEPTH_INFINITE, subMonitor);
161: break;
162: }
163: case MarkerFieldFilterGroup.ON_ANY_IN_SAME_CONTAINER: {
164: findMarkers(returnMarkers, getProjects(focusResources),
165: filterGroup, IResource.DEPTH_INFINITE, subMonitor);
166: break;
167: }
168: case MarkerFieldFilterGroup.ON_WORKING_SET: {
169: findMarkers(returnMarkers, getResourcesInWorkingSet(),
170: filterGroup, IResource.DEPTH_INFINITE, subMonitor);
171: }
172: }
173:
174: }
175:
176: /**
177: * Adds all markers in the given set of resources to the given list
178: *
179: * @param results
180: * The Collection to add new entries to
181: * @param resources
182: * @param group
183: * the group to filter on. May be <code>null</code>.
184: * @param depth
185: * @param monitor
186: */
187: private void findMarkers(Collection results, IResource[] resources,
188: MarkerFieldFilterGroup group, int depth,
189: IProgressMonitor monitor) {
190: if (resources == null) {
191: return;
192: }
193:
194: // Optimisation: if a type appears in the selectedTypes list along with
195: // all of its sub-types, then combine these in a single search.
196:
197: Collection selectedTypes = getMarkerTypes();
198:
199: // List of types that haven't been replaced by one of their super-types
200: HashSet typesToSearch = new HashSet(selectedTypes.size());
201:
202: // List of types that appeared in selectedTypes along with all of their
203: // sub-types
204: HashSet includeAllSubtypes = new HashSet(selectedTypes.size());
205:
206: typesToSearch.addAll(selectedTypes);
207:
208: Iterator iter = selectedTypes.iterator();
209:
210: while (iter.hasNext()) {
211: MarkerType type = (MarkerType) iter.next();
212:
213: Collection subtypes = Arrays.asList(type.getAllSubTypes());
214:
215: if (selectedTypes.containsAll(subtypes)) {
216: typesToSearch.removeAll(subtypes);
217:
218: includeAllSubtypes.add(type);
219: }
220: }
221:
222: monitor.beginTask(MarkerMessages.MarkerFilter_searching,
223: typesToSearch.size() * resources.length);
224:
225: // Use this hash set to determine if there are any resources in the
226: // list that appear along with their parent.
227: HashSet resourcesToSearch = new HashSet();
228:
229: // Insert all the resources into the Set
230: for (int idx = 0; idx < resources.length; idx++) {
231: IResource next = resources[idx];
232:
233: if (!next.exists())
234: continue;
235:
236: if (resourcesToSearch.contains(next))
237: monitor.worked(typesToSearch.size());
238: else
239: resourcesToSearch.add(next);
240: }
241:
242: // Iterate through all the selected resources
243: for (int resourceIdx = 0; resourceIdx < resources.length; resourceIdx++) {
244: iter = typesToSearch.iterator();
245:
246: IResource resource = resources[resourceIdx];
247:
248: // Skip resources that don't exist
249: if (!resource.isAccessible()) {
250: continue;
251: }
252:
253: if (depth == IResource.DEPTH_INFINITE) {
254: // Determine if any parent of this resource is also in our
255: // filter
256: IResource parent = resource.getParent();
257: boolean found = false;
258: while (parent != null) {
259: if (resourcesToSearch.contains(parent)) {
260: found = true;
261: }
262:
263: parent = parent.getParent();
264: }
265:
266: // If a parent of this resource is also in the filter, we can
267: // skip it
268: // because we'll pick up its markers when we search the parent.
269: if (found) {
270: continue;
271: }
272: }
273:
274: // Iterate through all the marker types
275: while (iter.hasNext()) {
276: MarkerType markerType = (MarkerType) iter.next();
277: try {
278: // Only search for sub-types of the marker if we found all
279: // of
280: // its sub-types in the filter criteria.
281: IMarker[] markers = resource.findMarkers(markerType
282: .getId(), includeAllSubtypes
283: .contains(markerType), depth);
284:
285: monitor.worked(1);
286:
287: for (int idx = 0; idx < markers.length; idx++) {
288: MarkerItem marker;
289: marker = new MarkerEntry(markers[idx]);
290: if (group == null || group.select(markers[idx]))
291: results.add(marker);
292: }
293: } catch (CoreException e) {
294: StatusManager.getManager().handle(e.getStatus());
295: }
296: }
297: }
298:
299: monitor.done();
300: }
301:
302: /**
303: * Re-generate all of the markers and filter them based on the enabled
304: * filters.
305: *
306: * @param subMonitor
307: * @return MarkerMap
308: */
309: public MarkerMap generateFilteredMarkers(
310: SubProgressMonitor subMonitor) {
311:
312: Collection filters = getEnabledFilters();
313: Collection returnMarkers;
314: if (filters.size() > 0) {
315: returnMarkers = new HashSet();
316: Iterator filtersIterator = filters.iterator();
317: while (filtersIterator.hasNext()) {
318: computeMarkers(returnMarkers, subMonitor,
319: (MarkerFieldFilterGroup) filtersIterator.next());
320: }
321:
322: } else
323: returnMarkers = computeAllMarkers(subMonitor);
324: MarkerEntry[] entries = new MarkerEntry[returnMarkers.size()];
325: returnMarkers.toArray(entries);
326: return new MarkerMap(entries);
327: }
328:
329: /**
330: * Get the all of the fields that this content generator is using.
331: *
332: * @return {@link MarkerField}[]
333: */
334: public MarkerField[] getAllFields() {
335: return allFields;
336: }
337:
338: /**
339: * Return all of the filters for the receiver.
340: *
341: * @return Collection of MarkerFieldFilterGroup
342: */
343: public Collection getAllFilters() {
344: if (filters == null) {
345: filters = new ArrayList();
346: IConfigurationElement[] filterReferences = configurationElement
347: .getChildren(ELEMENT_MARKER_FIELD_FILTER_GROUP);
348: for (int i = 0; i < filterReferences.length; i++) {
349: filters.add(new MarkerFieldFilterGroup(
350: filterReferences[i], this ));
351: }
352: // Apply the last settings
353: loadFiltersPreference();
354:
355: }
356: return filters;
357: }
358:
359: /**
360: * Return the group used to generate categories.
361: *
362: * @return MarkerGroup or <code>null</code>.
363: */
364: public MarkerGroup getCategoryGroup() {
365:
366: return categoryGroup;
367: }
368:
369: /**
370: * Return a new instance of the receiver with the field
371: *
372: * @return MarkerComparator
373: */
374: public MarkerComparator getComparator() {
375:
376: MarkerField field = null;
377: if (getCategoryGroup() != null)
378: field = getCategoryGroup().getMarkerField();
379: return new MarkerComparator(field, getAllFields());
380: }
381:
382: /**
383: * Get the id of the perspective this content generator is the default for.
384: *
385: * @return String or <code>null</code>.
386: */
387: public String getDefaultPerspectiveId() {
388: return configurationElement
389: .getAttribute(ATTRIBUTE_DEFAULT_FOR_PERSPECTIVE);
390: }
391:
392: /**
393: * Return the currently enabled filters.
394: *
395: * @return Collection of MarkerFieldFilterGroup
396: */
397: public Collection getEnabledFilters() {
398: if (enabledFilters == null) {
399: enabledFilters = new HashSet();
400: Iterator filtersIterator = getAllFilters().iterator();
401: while (filtersIterator.hasNext()) {
402: MarkerFieldFilterGroup next = (MarkerFieldFilterGroup) filtersIterator
403: .next();
404: if (next.isEnabled())
405: enabledFilters.add(next);
406: }
407: }
408: return enabledFilters;
409: }
410:
411: /**
412: * Return a collection of all of the configuration fields for this generator
413: *
414: * @return Collection of {@link FilterConfigurationArea}
415: */
416: public Collection getFilterConfigurationFields() {
417: Collection result = new ArrayList();
418: for (int i = 0; i < visibleFields.length; i++) {
419: FilterConfigurationArea area = visibleFields[i]
420: .generateFilterArea();
421: if (area != null)
422: result.add(area);
423:
424: }
425: return result;
426: }
427:
428: /**
429: * Return the id of the receiver.
430: *
431: * @return String
432: */
433: public String getId() {
434: return configurationElement
435: .getAttribute(MarkerSupportConstants.ATTRIBUTE_ID);
436: }
437:
438: /**
439: * Return the markerTypes for the receiver.
440: *
441: * @return Collection of {@link MarkerType}
442: */
443: public Collection getMarkerTypes() {
444: if (markerTypes == null) {
445: markerTypes = new HashSet();
446: IConfigurationElement[] markerTypeElements = configurationElement
447: .getChildren(MarkerSupportRegistry.MARKER_TYPE_REFERENCE);
448: for (int i = 0; i < markerTypeElements.length; i++) {
449: IConfigurationElement configurationElement = markerTypeElements[i];
450: String elementName = configurationElement
451: .getAttribute(MarkerSupportConstants.ATTRIBUTE_ID);
452: MarkerType[] types = MarkerTypesModel.getInstance()
453: .getType(elementName).getAllSubTypes();
454: for (int j = 0; j < types.length; j++) {
455: markerTypes.add(types[j]);
456: }
457: markerTypes.add(MarkerTypesModel.getInstance().getType(
458: elementName));
459: }
460: if (markerTypes.isEmpty()) {
461: MarkerType[] types = MarkerTypesModel.getInstance()
462: .getType(IMarker.PROBLEM).getAllSubTypes();
463: for (int i = 0; i < types.length; i++) {
464: markerTypes.add(types[i]);
465: }
466: }
467: }
468: return markerTypes;
469: }
470:
471: /**
472: * Get the name for the preferences for the receiver.
473: *
474: * @return String
475: */
476: private String getMementoPreferenceName() {
477: return getClass().getName() + getId();
478: }
479:
480: /**
481: * Return the name for the receiver.
482: *
483: * @return String
484: */
485: public String getName() {
486: return configurationElement
487: .getAttribute(MarkerSupportConstants.ATTRIBUTE_NAME);
488: }
489:
490: /**
491: * Return all of the projects being shown.
492: * @param focusResources
493: * @return IResource[]
494: */
495: private IResource[] getProjects(IResource[] focusResources) {
496:
497: if (focusResources.length == 0)
498: return EMPTY_RESOURCE_ARRAY;
499: HashSet projects = new HashSet();
500:
501: for (int idx = 0; idx < focusResources.length; idx++) {
502: projects.add(focusResources[idx].getProject());
503: }
504: if (projects.isEmpty())
505: return EMPTY_RESOURCE_ARRAY;
506: return (IResource[]) projects.toArray(new IResource[projects
507: .size()]);
508:
509: }
510:
511: /**
512: * Get the resources in the current working set.
513: *
514: * @return IResource[]
515: */
516: private IResource[] getResourcesInWorkingSet() {
517:
518: // TODO hook up working sets
519: if (workingSet == null) {
520: return new IResource[0];
521: }
522:
523: if (workingSet.isEmpty()) {
524: return new IResource[] { ResourcesPlugin.getWorkspace()
525: .getRoot() };
526: }
527:
528: IAdaptable[] elements = workingSet.getElements();
529: List result = new ArrayList(elements.length);
530:
531: for (int idx = 0; idx < elements.length; idx++) {
532: IResource next = (IResource) elements[idx]
533: .getAdapter(IResource.class);
534:
535: if (next != null) {
536: result.add(next);
537: }
538: }
539:
540: return (IResource[]) result
541: .toArray(new IResource[result.size()]);
542:
543: }
544:
545: /**
546: * Get the fields that this content generator is displaying.
547: *
548: * @return {@link MarkerField}[]
549: */
550: public MarkerField[] getVisibleFields() {
551: return visibleFields;
552: }
553:
554: /**
555: * Initialise the receiver from the configuration element. This is done as a
556: * post processing step.
557: *
558: * @param registry
559: * the MarkerSupportRegistry being used to initialise the
560: * receiver.
561: */
562: public void initializeFromConfigurationElement(
563: MarkerSupportRegistry registry) {
564: String categoryName = configurationElement
565: .getAttribute(ATTRIBUTE_DEFAULT_MARKER_GROUPING);
566: if (categoryName != null) {
567: MarkerGroup group = registry.getMarkerGroup(categoryName);
568: if (group != null)
569: categoryGroup = group;
570: }
571:
572: IConfigurationElement[] elements = configurationElement
573: .getChildren(MARKER_FIELD_REFERENCE);
574: Collection allFieldList = new ArrayList();
575: Collection visibleFieldList = new ArrayList();
576: for (int i = 0; i < elements.length; i++) {
577: MarkerField field = registry.getField(elements[i]
578: .getAttribute(MarkerSupportConstants.ATTRIBUTE_ID));
579: if (field == null)
580: continue;
581: allFieldList.add(field);
582: if (!VALUE_FALSE.equals(elements[i]
583: .getAttribute(ATTRIBUTE_VISIBLE)))
584: visibleFieldList.add(field);
585: }
586:
587: allFields = new MarkerField[allFieldList.size()];
588: allFieldList.toArray(allFields);
589:
590: visibleFields = new MarkerField[visibleFieldList.size()];
591: visibleFieldList.toArray(visibleFields);
592:
593: }
594:
595: /**
596: * Return whether or not we are showing a hierarchy,.
597: *
598: * @return <code>true</code> if a hierarchy is being shown.
599: */
600: public boolean isShowingHierarchy() {
601: return categoryGroup != null;
602: }
603:
604: /**
605: * Load the filters preference.
606: */
607: private void loadFiltersPreference() {
608:
609: String mementoString = IDEWorkbenchPlugin.getDefault()
610: .getPreferenceStore().getString(
611: getMementoPreferenceName());
612:
613: if (mementoString
614: .equals(IPreferenceStore.STRING_DEFAULT_DEFAULT))
615: return;
616:
617: try {
618: loadSettings(XMLMemento.createReadRoot(new StringReader(
619: mementoString)));
620: } catch (WorkbenchException e) {
621: StatusManager.getManager().handle(e.getStatus());
622: }
623: }
624:
625: /**
626: * Load the settings from the memento.
627: *
628: * @param memento
629: */
630: private void loadSettings(IMemento memento) {
631:
632: if (memento == null)
633: return;
634:
635: IMemento children[] = memento.getChildren(TAG_GROUP_ENTRY);
636:
637: for (int i = 0; i < children.length; i++) {
638: IMemento child = children[i];
639: String id = child.getString(IMemento.TAG_ID);
640: if (id == null)
641: continue;
642: Iterator groups = getAllFilters().iterator();
643: while (groups.hasNext()) {
644: MarkerFieldFilterGroup group = (MarkerFieldFilterGroup) groups
645: .next();
646: if (id.equals(group.getID()))
647: group.loadSettings(child);
648: continue;
649: }
650:
651: // Did not find a match must have been added by the user
652: loadUserFilter(child);
653: }
654:
655: }
656:
657: /**
658: * Load the user supplied filter
659: *
660: * @param child
661: */
662: private void loadUserFilter(IMemento child) {
663: // TODO Fill this in
664:
665: }
666:
667: /**
668: * Set the category group
669: *
670: * @param group
671: */
672: void setCategoryGroup(MarkerGroup group) {
673: this .categoryGroup = group;
674:
675: }
676:
677: /**
678: * Set the filters for the receiver.
679: *
680: * @param newFilters
681: */
682: public void setFilters(Collection newFilters) {
683: filters = newFilters;
684: enabledFilters = null;
685:
686: XMLMemento memento = XMLMemento
687: .createWriteRoot(TAG_FILTERS_SECTION);
688:
689: writeFiltersSettings(memento);
690:
691: StringWriter writer = new StringWriter();
692: try {
693: memento.save(writer);
694: } catch (IOException e) {
695: IDEWorkbenchPlugin.getDefault().getLog().log(
696: Util.errorStatus(e));
697: }
698:
699: IDEWorkbenchPlugin.getDefault().getPreferenceStore().putValue(
700: getMementoPreferenceName(), writer.toString());
701: IDEWorkbenchPlugin.getDefault().savePluginPreferences();
702: }
703:
704: /**
705: * Add group to the enabled filters.
706: *
707: * @param group
708: */
709: public void toggleFilter(MarkerFieldFilterGroup group) {
710: Collection enabled = getEnabledFilters();
711: if (enabled.remove(group))// true if it was present
712: return;
713: enabled.add(group);
714: }
715:
716: /**
717: * Update the focus resources from list. If there is an update required
718: * return <code>true</code>. This method assumes that there are filters
719: * on resources enabled.
720: *
721: * @param elements
722: */
723: void updateFocusElements(Object[] elements) {
724: Collection resourceCollection = new ArrayList();
725: for (int i = 0; i < elements.length; i++) {
726: if (elements[i] instanceof IResource) {
727: resourceCollection.add(elements[i]);
728: } else {
729: addResources(resourceCollection,
730: ((ResourceMapping) elements[i]));
731: }
732: }
733:
734: focusResources = new IResource[resourceCollection.size()];
735: resourceCollection.toArray(focusResources);
736: }
737:
738: /**
739: * Return whether or not the list contains a resource that will require
740: * regeneration.
741: *
742: * @return boolean <code>true</code> if regeneration is required.
743: */
744: boolean updateNeeded(Object[] newElements) {
745:
746: Iterator filters = getEnabledFilters().iterator();
747:
748: while (filters.hasNext()) {
749: MarkerFieldFilterGroup filter = (MarkerFieldFilterGroup) filters
750: .next();
751:
752: int scope = filter.getScope();
753: if (scope == MarkerFieldFilterGroup.ON_ANY
754: || scope == MarkerFieldFilterGroup.ON_WORKING_SET)
755: continue;
756:
757: if (newElements == null || newElements.length < 1)
758: continue;
759:
760: if (focusResources.length == 0)
761: return true; // We had nothing now we have something
762:
763: if (Arrays.equals(focusResources, newElements))
764: continue;
765:
766: if (scope == MarkerFieldFilterGroup.ON_ANY_IN_SAME_CONTAINER) {
767: Collection oldProjects = MarkerFieldFilterGroup
768: .getProjectsAsCollection(focusResources);
769: Collection newProjects = MarkerFieldFilterGroup
770: .getProjectsAsCollection(newElements);
771:
772: if (oldProjects.size() == newProjects.size()
773: && newProjects.containsAll(oldProjects))
774: continue;
775: return true;// Something must be different
776: }
777: return true;
778: }
779:
780: return false;
781: }
782:
783: /**
784: * Write the settings for the filters to the memento.
785: *
786: * @param memento
787: */
788: private void writeFiltersSettings(XMLMemento memento) {
789: Iterator groups = getAllFilters().iterator();
790: while (groups.hasNext()) {
791: MarkerFieldFilterGroup group = (MarkerFieldFilterGroup) groups
792: .next();
793: IMemento child = memento.createChild(TAG_GROUP_ENTRY, group
794: .getID());
795: group.saveFilterSettings(child);
796: }
797:
798: }
799:
800: }
|