001: /*******************************************************************************
002: * Copyright (c) 2000, 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.activities;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.Collections;
015: import java.util.HashMap;
016: import java.util.HashSet;
017: import java.util.Iterator;
018: import java.util.LinkedList;
019: import java.util.List;
020: import java.util.Map;
021: import java.util.Set;
022: import java.util.TreeMap;
023: import java.util.WeakHashMap;
024:
025: import org.eclipse.core.runtime.IProgressMonitor;
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.jobs.Job;
030: import org.eclipse.ui.activities.ActivityEvent;
031: import org.eclipse.ui.activities.ActivityManagerEvent;
032: import org.eclipse.ui.activities.CategoryEvent;
033: import org.eclipse.ui.activities.IActivity;
034: import org.eclipse.ui.activities.IActivityPatternBinding;
035: import org.eclipse.ui.activities.IActivityRequirementBinding;
036: import org.eclipse.ui.activities.ICategory;
037: import org.eclipse.ui.activities.ICategoryActivityBinding;
038: import org.eclipse.ui.activities.IIdentifier;
039: import org.eclipse.ui.activities.IMutableActivityManager;
040: import org.eclipse.ui.activities.IdentifierEvent;
041: import org.eclipse.ui.internal.util.Util;
042:
043: /**
044: * An activity registry that may be altered.
045: *
046: * @since 3.0
047: */
048: public final class MutableActivityManager extends
049: AbstractActivityManager implements IMutableActivityManager,
050: Cloneable {
051:
052: private Map activitiesById = new WeakHashMap();
053:
054: private Map activityRequirementBindingsByActivityId = new HashMap();
055:
056: private Map activityDefinitionsById = new HashMap();
057:
058: private Map activityPatternBindingsByActivityId = new HashMap();
059:
060: private IActivityRegistry activityRegistry;
061:
062: private Map categoriesById = new WeakHashMap();
063:
064: private Map categoryActivityBindingsByCategoryId = new HashMap();
065:
066: private Map categoryDefinitionsById = new HashMap();
067:
068: private Set definedActivityIds = new HashSet();
069:
070: private Set definedCategoryIds = new HashSet();
071:
072: private Set enabledActivityIds = new HashSet();
073:
074: private Map identifiersById = new WeakHashMap();
075:
076: /**
077: * A list of identifiers that need to have their activity sets reconciled in the background job.
078: */
079: private List deferredIdentifiers = Collections
080: .synchronizedList(new LinkedList());
081:
082: /**
083: * The identifier update job. Lazily initialized.
084: */
085: private Job deferredIdentifierJob = null;
086:
087: private final IActivityRegistryListener activityRegistryListener = new IActivityRegistryListener() {
088: public void activityRegistryChanged(
089: ActivityRegistryEvent activityRegistryEvent) {
090: readRegistry(false);
091: }
092: };
093:
094: /**
095: * Create a new instance of this class using the platform extension registry.
096: */
097: public MutableActivityManager() {
098: this (new ExtensionActivityRegistry(Platform
099: .getExtensionRegistry()));
100: }
101:
102: /**
103: * Create a new instance of this class using the provided registry.
104: *
105: * @param activityRegistry the activity registry
106: */
107: public MutableActivityManager(IActivityRegistry activityRegistry) {
108: if (activityRegistry == null) {
109: throw new NullPointerException();
110: }
111:
112: this .activityRegistry = activityRegistry;
113:
114: this .activityRegistry
115: .addActivityRegistryListener(activityRegistryListener);
116:
117: readRegistry(true);
118: }
119:
120: public IActivity getActivity(String activityId) {
121: if (activityId == null) {
122: throw new NullPointerException();
123: }
124:
125: Activity activity = (Activity) activitiesById.get(activityId);
126:
127: if (activity == null) {
128: activity = new Activity(activityId);
129: updateActivity(activity);
130: activitiesById.put(activityId, activity);
131: }
132:
133: return activity;
134: }
135:
136: public ICategory getCategory(String categoryId) {
137: if (categoryId == null) {
138: throw new NullPointerException();
139: }
140:
141: Category category = (Category) categoriesById.get(categoryId);
142:
143: if (category == null) {
144: category = new Category(categoryId);
145: updateCategory(category);
146: categoriesById.put(categoryId, category);
147: }
148:
149: return category;
150: }
151:
152: public Set getDefinedActivityIds() {
153: return Collections.unmodifiableSet(definedActivityIds);
154: }
155:
156: public Set getDefinedCategoryIds() {
157: return Collections.unmodifiableSet(definedCategoryIds);
158: }
159:
160: public Set getEnabledActivityIds() {
161: return Collections.unmodifiableSet(enabledActivityIds);
162: }
163:
164: public IIdentifier getIdentifier(String identifierId) {
165: if (identifierId == null) {
166: throw new NullPointerException();
167: }
168:
169: Identifier identifier = (Identifier) identifiersById
170: .get(identifierId);
171:
172: if (identifier == null) {
173: identifier = new Identifier(identifierId);
174: updateIdentifier(identifier);
175: identifiersById.put(identifierId, identifier);
176: }
177:
178: return identifier;
179: }
180:
181: private void getRequiredActivityIds(Set activityIds,
182: Set requiredActivityIds) {
183: for (Iterator iterator = activityIds.iterator(); iterator
184: .hasNext();) {
185: String activityId = (String) iterator.next();
186: IActivity activity = getActivity(activityId);
187: Set childActivityIds = new HashSet();
188: Set activityRequirementBindings = activity
189: .getActivityRequirementBindings();
190:
191: for (Iterator iterator2 = activityRequirementBindings
192: .iterator(); iterator2.hasNext();) {
193: IActivityRequirementBinding activityRequirementBinding = (IActivityRequirementBinding) iterator2
194: .next();
195: childActivityIds.add(activityRequirementBinding
196: .getRequiredActivityId());
197: }
198:
199: childActivityIds.removeAll(requiredActivityIds);
200: requiredActivityIds.addAll(childActivityIds);
201: getRequiredActivityIds(childActivityIds,
202: requiredActivityIds);
203: }
204: }
205:
206: private void notifyActivities(Map activityEventsByActivityId) {
207: for (Iterator iterator = activityEventsByActivityId.entrySet()
208: .iterator(); iterator.hasNext();) {
209: Map.Entry entry = (Map.Entry) iterator.next();
210: String activityId = (String) entry.getKey();
211: ActivityEvent activityEvent = (ActivityEvent) entry
212: .getValue();
213: Activity activity = (Activity) activitiesById
214: .get(activityId);
215:
216: if (activity != null) {
217: activity.fireActivityChanged(activityEvent);
218: }
219: }
220: }
221:
222: private void notifyCategories(Map categoryEventsByCategoryId) {
223: for (Iterator iterator = categoryEventsByCategoryId.entrySet()
224: .iterator(); iterator.hasNext();) {
225: Map.Entry entry = (Map.Entry) iterator.next();
226: String categoryId = (String) entry.getKey();
227: CategoryEvent categoryEvent = (CategoryEvent) entry
228: .getValue();
229: Category category = (Category) categoriesById
230: .get(categoryId);
231:
232: if (category != null) {
233: category.fireCategoryChanged(categoryEvent);
234: }
235: }
236: }
237:
238: private void notifyIdentifiers(Map identifierEventsByIdentifierId) {
239: for (Iterator iterator = identifierEventsByIdentifierId
240: .entrySet().iterator(); iterator.hasNext();) {
241: Map.Entry entry = (Map.Entry) iterator.next();
242: String identifierId = (String) entry.getKey();
243: IdentifierEvent identifierEvent = (IdentifierEvent) entry
244: .getValue();
245: Identifier identifier = (Identifier) identifiersById
246: .get(identifierId);
247:
248: if (identifier != null) {
249: identifier.fireIdentifierChanged(identifierEvent);
250: }
251: }
252: }
253:
254: private void readRegistry(boolean setDefaults) {
255: if (!isRegexpSupported()) {
256: return;
257: }
258: Collection activityDefinitions = new ArrayList();
259: activityDefinitions.addAll(activityRegistry
260: .getActivityDefinitions());
261: Map activityDefinitionsById = new HashMap(ActivityDefinition
262: .activityDefinitionsById(activityDefinitions, false));
263:
264: for (Iterator iterator = activityDefinitionsById.values()
265: .iterator(); iterator.hasNext();) {
266: ActivityDefinition activityDefinition = (ActivityDefinition) iterator
267: .next();
268: String name = activityDefinition.getName();
269:
270: if (name == null || name.length() == 0) {
271: iterator.remove();
272: }
273: }
274:
275: Collection categoryDefinitions = new ArrayList();
276: categoryDefinitions.addAll(activityRegistry
277: .getCategoryDefinitions());
278: Map categoryDefinitionsById = new HashMap(CategoryDefinition
279: .categoryDefinitionsById(categoryDefinitions, false));
280:
281: for (Iterator iterator = categoryDefinitionsById.values()
282: .iterator(); iterator.hasNext();) {
283: CategoryDefinition categoryDefinition = (CategoryDefinition) iterator
284: .next();
285: String name = categoryDefinition.getName();
286:
287: if (name == null || name.length() == 0) {
288: iterator.remove();
289: }
290: }
291:
292: Map activityRequirementBindingDefinitionsByActivityId = ActivityRequirementBindingDefinition
293: .activityRequirementBindingDefinitionsByActivityId(activityRegistry
294: .getActivityRequirementBindingDefinitions());
295: Map activityRequirementBindingsByActivityId = new HashMap();
296:
297: for (Iterator iterator = activityRequirementBindingDefinitionsByActivityId
298: .entrySet().iterator(); iterator.hasNext();) {
299: Map.Entry entry = (Map.Entry) iterator.next();
300: String parentActivityId = (String) entry.getKey();
301:
302: if (activityDefinitionsById.containsKey(parentActivityId)) {
303: Collection activityRequirementBindingDefinitions = (Collection) entry
304: .getValue();
305:
306: if (activityRequirementBindingDefinitions != null) {
307: for (Iterator iterator2 = activityRequirementBindingDefinitions
308: .iterator(); iterator2.hasNext();) {
309: ActivityRequirementBindingDefinition activityRequirementBindingDefinition = (ActivityRequirementBindingDefinition) iterator2
310: .next();
311: String childActivityId = activityRequirementBindingDefinition
312: .getRequiredActivityId();
313:
314: if (activityDefinitionsById
315: .containsKey(childActivityId)) {
316: IActivityRequirementBinding activityRequirementBinding = new ActivityRequirementBinding(
317: childActivityId, parentActivityId);
318: Set activityRequirementBindings = (Set) activityRequirementBindingsByActivityId
319: .get(parentActivityId);
320:
321: if (activityRequirementBindings == null) {
322: activityRequirementBindings = new HashSet();
323: activityRequirementBindingsByActivityId
324: .put(parentActivityId,
325: activityRequirementBindings);
326: }
327:
328: activityRequirementBindings
329: .add(activityRequirementBinding);
330: }
331: }
332: }
333: }
334: }
335:
336: Map activityPatternBindingDefinitionsByActivityId = ActivityPatternBindingDefinition
337: .activityPatternBindingDefinitionsByActivityId(activityRegistry
338: .getActivityPatternBindingDefinitions());
339: Map activityPatternBindingsByActivityId = new HashMap();
340:
341: for (Iterator iterator = activityPatternBindingDefinitionsByActivityId
342: .entrySet().iterator(); iterator.hasNext();) {
343: Map.Entry entry = (Map.Entry) iterator.next();
344: String activityId = (String) entry.getKey();
345:
346: if (activityDefinitionsById.containsKey(activityId)) {
347: Collection activityPatternBindingDefinitions = (Collection) entry
348: .getValue();
349:
350: if (activityPatternBindingDefinitions != null) {
351: for (Iterator iterator2 = activityPatternBindingDefinitions
352: .iterator(); iterator2.hasNext();) {
353: ActivityPatternBindingDefinition activityPatternBindingDefinition = (ActivityPatternBindingDefinition) iterator2
354: .next();
355: String pattern = activityPatternBindingDefinition
356: .getPattern();
357:
358: if (pattern != null && pattern.length() != 0) {
359: IActivityPatternBinding activityPatternBinding = new ActivityPatternBinding(
360: activityId, pattern);
361: Set activityPatternBindings = (Set) activityPatternBindingsByActivityId
362: .get(activityId);
363:
364: if (activityPatternBindings == null) {
365: activityPatternBindings = new HashSet();
366: activityPatternBindingsByActivityId
367: .put(activityId,
368: activityPatternBindings);
369: }
370:
371: activityPatternBindings
372: .add(activityPatternBinding);
373: }
374: }
375: }
376: }
377: }
378:
379: Map categoryActivityBindingDefinitionsByCategoryId = CategoryActivityBindingDefinition
380: .categoryActivityBindingDefinitionsByCategoryId(activityRegistry
381: .getCategoryActivityBindingDefinitions());
382: Map categoryActivityBindingsByCategoryId = new HashMap();
383:
384: for (Iterator iterator = categoryActivityBindingDefinitionsByCategoryId
385: .entrySet().iterator(); iterator.hasNext();) {
386: Map.Entry entry = (Map.Entry) iterator.next();
387: String categoryId = (String) entry.getKey();
388:
389: if (categoryDefinitionsById.containsKey(categoryId)) {
390: Collection categoryActivityBindingDefinitions = (Collection) entry
391: .getValue();
392:
393: if (categoryActivityBindingDefinitions != null) {
394: for (Iterator iterator2 = categoryActivityBindingDefinitions
395: .iterator(); iterator2.hasNext();) {
396: CategoryActivityBindingDefinition categoryActivityBindingDefinition = (CategoryActivityBindingDefinition) iterator2
397: .next();
398: String activityId = categoryActivityBindingDefinition
399: .getActivityId();
400:
401: if (activityDefinitionsById
402: .containsKey(activityId)) {
403: ICategoryActivityBinding categoryActivityBinding = new CategoryActivityBinding(
404: activityId, categoryId);
405: Set categoryActivityBindings = (Set) categoryActivityBindingsByCategoryId
406: .get(categoryId);
407:
408: if (categoryActivityBindings == null) {
409: categoryActivityBindings = new HashSet();
410: categoryActivityBindingsByCategoryId
411: .put(categoryId,
412: categoryActivityBindings);
413: }
414:
415: categoryActivityBindings
416: .add(categoryActivityBinding);
417: }
418: }
419: }
420: }
421: }
422:
423: this .activityRequirementBindingsByActivityId = activityRequirementBindingsByActivityId;
424: this .activityDefinitionsById = activityDefinitionsById;
425: this .activityPatternBindingsByActivityId = activityPatternBindingsByActivityId;
426: this .categoryActivityBindingsByCategoryId = categoryActivityBindingsByCategoryId;
427: this .categoryDefinitionsById = categoryDefinitionsById;
428: boolean definedActivityIdsChanged = false;
429: Set definedActivityIds = new HashSet(activityDefinitionsById
430: .keySet());
431:
432: Set previouslyDefinedActivityIds = null;
433: if (!definedActivityIds.equals(this .definedActivityIds)) {
434: previouslyDefinedActivityIds = this .definedActivityIds;
435: this .definedActivityIds = definedActivityIds;
436: definedActivityIdsChanged = true;
437: }
438:
439: boolean definedCategoryIdsChanged = false;
440: Set definedCategoryIds = new HashSet(categoryDefinitionsById
441: .keySet());
442:
443: Set previouslyDefinedCategoryIds = null;
444: if (!definedCategoryIds.equals(this .definedCategoryIds)) {
445: previouslyDefinedCategoryIds = this .definedCategoryIds;
446: this .definedCategoryIds = definedCategoryIds;
447: definedCategoryIdsChanged = true;
448: }
449:
450: Set enabledActivityIds = new HashSet(this .enabledActivityIds);
451: getRequiredActivityIds(this .enabledActivityIds,
452: enabledActivityIds);
453: boolean enabledActivityIdsChanged = false;
454:
455: Set previouslyEnabledActivityIds = null;
456: if (!this .enabledActivityIds.equals(enabledActivityIds)) {
457: previouslyEnabledActivityIds = this .enabledActivityIds;
458: this .enabledActivityIds = enabledActivityIds;
459: enabledActivityIdsChanged = true;
460: }
461:
462: Map activityEventsByActivityId = updateActivities(activitiesById
463: .keySet());
464:
465: Map categoryEventsByCategoryId = updateCategories(categoriesById
466: .keySet());
467:
468: Map identifierEventsByIdentifierId = updateIdentifiers(identifiersById
469: .keySet());
470:
471: if (definedActivityIdsChanged || definedCategoryIdsChanged
472: || enabledActivityIdsChanged) {
473: fireActivityManagerChanged(new ActivityManagerEvent(this ,
474: definedActivityIdsChanged,
475: definedCategoryIdsChanged,
476: enabledActivityIdsChanged,
477: previouslyDefinedActivityIds,
478: previouslyDefinedCategoryIds,
479: previouslyEnabledActivityIds));
480: }
481:
482: if (activityEventsByActivityId != null) {
483: notifyActivities(activityEventsByActivityId);
484: }
485:
486: if (categoryEventsByCategoryId != null) {
487: notifyCategories(categoryEventsByCategoryId);
488: }
489:
490: if (identifierEventsByIdentifierId != null) {
491: notifyIdentifiers(identifierEventsByIdentifierId);
492: }
493:
494: if (setDefaults) {
495: setEnabledActivityIds(new HashSet(activityRegistry
496: .getDefaultEnabledActivities()));
497: }
498: }
499:
500: /**
501: * Returns whether the Java 1.4 regular expression support is available.
502: * Regexp support will not be available when running against JCL Foundation (see bug 80053).
503: *
504: * @return <code>true</code> if regexps are supported, <code>false</code> otherwise.
505: *
506: * @since 3.1
507: */
508: private boolean isRegexpSupported() {
509: try {
510: Class.forName("java.util.regex.Pattern"); //$NON-NLS-1$
511: return true;
512: } catch (Exception e) {
513: return false;
514: }
515: }
516:
517: public void setEnabledActivityIds(Set enabledActivityIds) {
518: enabledActivityIds = Util.safeCopy(enabledActivityIds,
519: String.class);
520: Set requiredActivityIds = new HashSet(enabledActivityIds);
521: getRequiredActivityIds(enabledActivityIds, requiredActivityIds);
522: enabledActivityIds = requiredActivityIds;
523: boolean activityManagerChanged = false;
524: Map activityEventsByActivityId = null;
525: Set deltaActivityIds = null;
526: Set previouslyEnabledActivityIds = null;
527: if (!this .enabledActivityIds.equals(enabledActivityIds)) {
528: previouslyEnabledActivityIds = this .enabledActivityIds;
529: this .enabledActivityIds = enabledActivityIds;
530: activityManagerChanged = true;
531:
532: // compute delta of activity changes
533: deltaActivityIds = new HashSet(previouslyEnabledActivityIds);
534: deltaActivityIds.removeAll(enabledActivityIds);
535: Set temp = new HashSet(enabledActivityIds);
536: temp.removeAll(previouslyEnabledActivityIds);
537: deltaActivityIds.addAll(temp);
538:
539: activityEventsByActivityId = updateActivities(deltaActivityIds);
540: }
541:
542: //don't update identifiers if the enabled activity set has not changed
543: if (activityManagerChanged) {
544: Map identifierEventsByIdentifierId = updateIdentifiers(
545: identifiersById.keySet(), deltaActivityIds);
546: if (identifierEventsByIdentifierId != null) {
547: notifyIdentifiers(identifierEventsByIdentifierId);
548: }
549: }
550: if (activityEventsByActivityId != null) {
551: notifyActivities(activityEventsByActivityId);
552: }
553:
554: if (activityManagerChanged) {
555: fireActivityManagerChanged(new ActivityManagerEvent(this ,
556: false, false, true, null, null,
557: previouslyEnabledActivityIds));
558: }
559: }
560:
561: private Map updateActivities(Collection activityIds) {
562: Map activityEventsByActivityId = new TreeMap();
563:
564: for (Iterator iterator = activityIds.iterator(); iterator
565: .hasNext();) {
566: String activityId = (String) iterator.next();
567: Activity activity = (Activity) activitiesById
568: .get(activityId);
569:
570: if (activity != null) {
571: ActivityEvent activityEvent = updateActivity(activity);
572:
573: if (activityEvent != null) {
574: activityEventsByActivityId.put(activityId,
575: activityEvent);
576: }
577: }
578: }
579:
580: return activityEventsByActivityId;
581: }
582:
583: private ActivityEvent updateActivity(Activity activity) {
584: Set activityRequirementBindings = (Set) activityRequirementBindingsByActivityId
585: .get(activity.getId());
586: boolean activityRequirementBindingsChanged = activity
587: .setActivityRequirementBindings(activityRequirementBindings != null ? activityRequirementBindings
588: : Collections.EMPTY_SET);
589: Set activityPatternBindings = (Set) activityPatternBindingsByActivityId
590: .get(activity.getId());
591: boolean activityPatternBindingsChanged = activity
592: .setActivityPatternBindings(activityPatternBindings != null ? activityPatternBindings
593: : Collections.EMPTY_SET);
594: ActivityDefinition activityDefinition = (ActivityDefinition) activityDefinitionsById
595: .get(activity.getId());
596: boolean definedChanged = activity
597: .setDefined(activityDefinition != null);
598: boolean enabledChanged = activity.setEnabled(enabledActivityIds
599: .contains(activity.getId()));
600: boolean nameChanged = activity
601: .setName(activityDefinition != null ? activityDefinition
602: .getName()
603: : null);
604: boolean descriptionChanged = activity
605: .setDescription(activityDefinition != null ? activityDefinition
606: .getDescription()
607: : null);
608: boolean defaultEnabledChanged = activity
609: .setDefaultEnabled(activityRegistry
610: .getDefaultEnabledActivities().contains(
611: activity.getId()));
612: if (activityRequirementBindingsChanged
613: || activityPatternBindingsChanged || definedChanged
614: || enabledChanged || nameChanged || descriptionChanged
615: || defaultEnabledChanged) {
616: return new ActivityEvent(activity,
617: activityRequirementBindingsChanged,
618: activityPatternBindingsChanged, definedChanged,
619: descriptionChanged, enabledChanged, nameChanged,
620: defaultEnabledChanged);
621: }
622:
623: return null;
624: }
625:
626: private Map updateCategories(Collection categoryIds) {
627: Map categoryEventsByCategoryId = new TreeMap();
628:
629: for (Iterator iterator = categoryIds.iterator(); iterator
630: .hasNext();) {
631: String categoryId = (String) iterator.next();
632: Category category = (Category) categoriesById
633: .get(categoryId);
634:
635: if (category != null) {
636: CategoryEvent categoryEvent = updateCategory(category);
637:
638: if (categoryEvent != null) {
639: categoryEventsByCategoryId.put(categoryId,
640: categoryEvent);
641: }
642: }
643: }
644:
645: return categoryEventsByCategoryId;
646: }
647:
648: private CategoryEvent updateCategory(Category category) {
649: Set categoryActivityBindings = (Set) categoryActivityBindingsByCategoryId
650: .get(category.getId());
651: boolean categoryActivityBindingsChanged = category
652: .setCategoryActivityBindings(categoryActivityBindings != null ? categoryActivityBindings
653: : Collections.EMPTY_SET);
654: CategoryDefinition categoryDefinition = (CategoryDefinition) categoryDefinitionsById
655: .get(category.getId());
656: boolean definedChanged = category
657: .setDefined(categoryDefinition != null);
658: boolean nameChanged = category
659: .setName(categoryDefinition != null ? categoryDefinition
660: .getName()
661: : null);
662: boolean descriptionChanged = category
663: .setDescription(categoryDefinition != null ? categoryDefinition
664: .getDescription()
665: : null);
666:
667: if (categoryActivityBindingsChanged || definedChanged
668: || nameChanged || descriptionChanged) {
669: return new CategoryEvent(category,
670: categoryActivityBindingsChanged, definedChanged,
671: descriptionChanged, nameChanged);
672: }
673:
674: return null;
675: }
676:
677: private IdentifierEvent updateIdentifier(Identifier identifier) {
678: return updateIdentifier(identifier, definedActivityIds);
679: }
680:
681: private IdentifierEvent updateIdentifier(Identifier identifier,
682: Set changedActivityIds) {
683: String id = identifier.getId();
684: Set activityIds = new HashSet();
685:
686: boolean enabled = false;
687:
688: boolean activityIdsChanged = false;
689:
690: boolean enabledChanged = false;
691:
692: // short-circut logic. If all activities are enabled, then the
693: // identifier must be as well. Return true and schedule the remainder of
694: // the work to run in a background job.
695: if (enabledActivityIds.size() == definedActivityIds.size()) {
696: enabled = true;
697: enabledChanged = identifier.setEnabled(enabled);
698: identifier.setActivityIds(Collections.EMPTY_SET);
699: deferredIdentifiers.add(identifier);
700: getUpdateJob().schedule();
701: if (enabledChanged) {
702: return new IdentifierEvent(identifier,
703: activityIdsChanged, enabledChanged);
704: }
705: } else {
706: boolean matchesAtLeastOneEnabled = false;
707: boolean matchesAtLeastOneDisabled = false;
708: Set activityIdsToUpdate = new HashSet(changedActivityIds);
709: if (identifier.getActivityIds() != null) {
710: activityIdsToUpdate.addAll(identifier.getActivityIds());
711: }
712: for (Iterator iterator = activityIdsToUpdate.iterator(); iterator
713: .hasNext();) {
714: String activityId = (String) iterator.next();
715: Activity activity = (Activity) getActivity(activityId);
716:
717: if (activity.isMatch(id)) {
718: activityIds.add(activityId);
719: if (activity.isEnabled()) {
720: matchesAtLeastOneEnabled = true;
721: } else {
722: matchesAtLeastOneDisabled = true;
723: }
724: }
725: }
726:
727: enabled = matchesAtLeastOneEnabled ? true
728: : !matchesAtLeastOneDisabled;
729:
730: activityIdsChanged = identifier.setActivityIds(activityIds);
731: enabledChanged = identifier.setEnabled(enabled);
732:
733: if (activityIdsChanged || enabledChanged) {
734: return new IdentifierEvent(identifier,
735: activityIdsChanged, enabledChanged);
736: }
737: }
738: return null;
739: }
740:
741: private Map updateIdentifiers(Collection identifierIds) {
742: return updateIdentifiers(identifierIds, definedActivityIds);
743: }
744:
745: private Map updateIdentifiers(Collection identifierIds,
746: Set changedActivityIds) {
747: Map identifierEventsByIdentifierId = new TreeMap();
748:
749: for (Iterator iterator = identifierIds.iterator(); iterator
750: .hasNext();) {
751: String identifierId = (String) iterator.next();
752: Identifier identifier = (Identifier) identifiersById
753: .get(identifierId);
754:
755: if (identifier != null) {
756: IdentifierEvent identifierEvent = updateIdentifier(
757: identifier, changedActivityIds);
758:
759: if (identifierEvent != null) {
760: identifierEventsByIdentifierId.put(identifierId,
761: identifierEvent);
762: }
763: }
764: }
765:
766: return identifierEventsByIdentifierId;
767: }
768:
769: /**
770: * Unhook this manager from its registry.
771: *
772: * @since 3.1
773: */
774: public void unhookRegistryListeners() {
775: activityRegistry
776: .removeActivityRegistryListener(activityRegistryListener);
777: }
778:
779: /* (non-Javadoc)
780: * @see java.lang.Object#clone()
781: */
782: public Object clone() {
783: MutableActivityManager clone = new MutableActivityManager(
784: activityRegistry);
785: clone.setEnabledActivityIds(getEnabledActivityIds());
786: return clone;
787: }
788:
789: /**
790: * Return the identifier update job.
791: *
792: * @return the job
793: * @since 3.1
794: */
795: private Job getUpdateJob() {
796: if (deferredIdentifierJob == null) {
797: deferredIdentifierJob = new Job("Identifier Update Job") { //$NON-NLS-1$
798:
799: /* (non-Javadoc)
800: * @see org.eclipse.core.internal.jobs.InternalJob#run(org.eclipse.core.runtime.IProgressMonitor)
801: */
802: protected IStatus run(IProgressMonitor monitor) {
803: while (!deferredIdentifiers.isEmpty()) {
804: Identifier identifier = (Identifier) deferredIdentifiers
805: .remove(0);
806: Set activityIds = new HashSet();
807: for (Iterator iterator = definedActivityIds
808: .iterator(); iterator.hasNext();) {
809: String activityId = (String) iterator
810: .next();
811: Activity activity = (Activity) getActivity(activityId);
812:
813: if (activity.isMatch(identifier.getId())) {
814: activityIds.add(activityId);
815: }
816: }
817:
818: boolean activityIdsChanged = identifier
819: .setActivityIds(activityIds);
820: if (activityIdsChanged) {
821: IdentifierEvent identifierEvent = new IdentifierEvent(
822: identifier, activityIdsChanged,
823: false);
824: Map identifierEventsByIdentifierId = new HashMap(
825: 1);
826: identifierEventsByIdentifierId
827: .put(identifier.getId(),
828: identifierEvent);
829: notifyIdentifiers(identifierEventsByIdentifierId);
830: }
831: }
832: return Status.OK_STATUS;
833: }
834: };
835: deferredIdentifierJob.setSystem(true);
836: }
837: return deferredIdentifierJob;
838: }
839: }
|