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.internal.contexts;
011:
012: import java.util.ArrayList;
013: import java.util.Comparator;
014: import java.util.HashSet;
015: import java.util.List;
016: import java.util.Set;
017: import java.util.SortedSet;
018: import java.util.TreeSet;
019:
020: import org.eclipse.core.commands.common.NotDefinedException;
021: import org.eclipse.core.commands.contexts.Context;
022: import org.eclipse.core.commands.contexts.ContextManager;
023: import org.eclipse.ui.contexts.ContextManagerEvent;
024: import org.eclipse.ui.contexts.IContext;
025: import org.eclipse.ui.contexts.IContextManager;
026: import org.eclipse.ui.contexts.IContextManagerListener;
027:
028: /**
029: * A wrapper around the new API that supports the old API. This manager also
030: * adds support for reading from the registry.
031: *
032: * @since 3.1
033: */
034: public final class ContextManagerLegacyWrapper implements
035: org.eclipse.core.commands.contexts.IContextManagerListener,
036: IContextManager {
037:
038: /**
039: * A comparator between context identifiers, that sorts them based on depth
040: * within the tree. Context identifiers representing deeper items (i.e.,
041: * items with more ancestors), have lesser values (i.e., would appear
042: * earlier in a set).
043: *
044: * @since 3.0
045: */
046: private class ContextIdDepthComparator implements Comparator {
047:
048: /**
049: * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
050: */
051: public final int compare(final Object object1,
052: final Object object2) {
053: final String contextId1 = (String) object1;
054: final String contextId2 = (String) object2;
055: Context context;
056: String parentId;
057:
058: // Get the depth of the first context.
059: int depth1 = 0;
060: context = contextManager.getContext(contextId1);
061: try {
062: parentId = context.getParentId();
063: while (parentId != null) {
064: depth1++;
065: context = contextManager.getContext(parentId);
066: parentId = context.getParentId();
067: }
068: } catch (final NotDefinedException e) {
069: // Do nothing. Stop ascending the ancestry.
070: }
071:
072: // Get the depth of the second context.
073: int depth2 = 0;
074: context = contextManager.getContext(contextId2);
075: try {
076: parentId = context.getParentId();
077: while (parentId != null) {
078: depth2++;
079: context = contextManager.getContext(parentId);
080: parentId = context.getParentId();
081: }
082: } catch (final NotDefinedException e) {
083: // Do nothing. Stop ascending the ancestry.
084: }
085:
086: // If the contexts are equal depth, then use their identifier.
087: int compare = depth2 - depth1;
088: if (compare == 0) {
089: compare = contextId1.compareTo(contextId2);
090: }
091:
092: return compare;
093: }
094: }
095:
096: /**
097: * A set that contains context identifiers (strings). The set is sorted
098: * based on how many ancestors the corresponding contexts have. Contexts
099: * with no parents appear last, while contexts with the most ancestors
100: * appear first.
101: *
102: * @since 3.0
103: */
104: private class DepthSortedContextIdSet extends TreeSet {
105:
106: /**
107: * Generated serial version UID for this class.
108: *
109: * @since 3.1
110: */
111: private static final long serialVersionUID = 3257291326872892465L;
112:
113: /**
114: * Constructs a new instance of <code>DepthSortedContextIdSet</code>
115: * with the set to be sorted.
116: *
117: * @param contextIds
118: * A set of context identifiers (strings); this may contain
119: * <code>null</code> values. The set may not be
120: * <code>null</code>, but may be empty.
121: */
122: private DepthSortedContextIdSet(final Set contextIds) {
123: super (new ContextIdDepthComparator());
124: addAll(contextIds);
125: }
126: }
127:
128: private final ContextManager contextManager;
129:
130: private List contextManagerListeners;
131:
132: /**
133: * Constructs a new instance of <code>MutableContextManager</code>. The
134: * registry is created on the platform's extension registry.
135: *
136: * @param contextManager
137: * The manager which will provided the real support; must not be
138: * <code>null</code>.
139: */
140: public ContextManagerLegacyWrapper(ContextManager contextManager) {
141:
142: if (contextManager == null) {
143: throw new NullPointerException(
144: "The context manager cannot be null"); //$NON-NLS-1$
145: }
146:
147: this .contextManager = contextManager;
148: this .contextManager.addContextManagerListener(this );
149: }
150:
151: public void addContextManagerListener(
152: IContextManagerListener contextManagerListener) {
153: if (contextManagerListener == null) {
154: throw new NullPointerException();
155: }
156:
157: if (contextManagerListeners == null) {
158: contextManagerListeners = new ArrayList();
159: }
160:
161: if (!contextManagerListeners.contains(contextManagerListener)) {
162: contextManagerListeners.add(contextManagerListener);
163: }
164: }
165:
166: /*
167: * (non-Javadoc)
168: *
169: * @see org.eclipse.core.commands.contexts.IContextManagerListener#contextManagerChanged(org.eclipse.core.commands.contexts.ContextManagerEvent)
170: */
171: public void contextManagerChanged(
172: org.eclipse.core.commands.contexts.ContextManagerEvent contextManagerEvent) {
173: final String contextId = contextManagerEvent.getContextId();
174: final boolean definedContextsChanged;
175: final Set previouslyDefinedContextIds;
176: if (contextId == null) {
177: definedContextsChanged = false;
178: previouslyDefinedContextIds = null;
179: } else {
180: definedContextsChanged = true;
181: previouslyDefinedContextIds = new HashSet();
182: previouslyDefinedContextIds.addAll(contextManager
183: .getDefinedContextIds());
184: if (contextManagerEvent.isContextDefined()) {
185: previouslyDefinedContextIds.remove(contextId);
186: } else {
187: previouslyDefinedContextIds.add(contextId);
188: }
189: }
190:
191: fireContextManagerChanged(new ContextManagerEvent(this ,
192: definedContextsChanged, contextManagerEvent
193: .isActiveContextsChanged(),
194: previouslyDefinedContextIds, contextManagerEvent
195: .getPreviouslyActiveContextIds()));
196:
197: }
198:
199: protected void fireContextManagerChanged(
200: ContextManagerEvent contextManagerEvent) {
201: if (contextManagerEvent == null) {
202: throw new NullPointerException();
203: }
204:
205: if (contextManagerListeners != null) {
206: for (int i = 0; i < contextManagerListeners.size(); i++) {
207: ((IContextManagerListener) contextManagerListeners
208: .get(i))
209: .contextManagerChanged(contextManagerEvent);
210: }
211: }
212: }
213:
214: public IContext getContext(String contextId) {
215: return new ContextLegacyWrapper(contextManager
216: .getContext(contextId), contextManager);
217: }
218:
219: public SortedSet getDefinedContextIds() {
220: return new DepthSortedContextIdSet(contextManager
221: .getDefinedContextIds());
222: }
223:
224: public SortedSet getEnabledContextIds() {
225: return new DepthSortedContextIdSet(contextManager
226: .getActiveContextIds());
227: }
228:
229: public void removeContextManagerListener(
230: IContextManagerListener contextManagerListener) {
231: if (contextManagerListener == null) {
232: throw new NullPointerException();
233: }
234:
235: if (contextManagerListeners != null) {
236: contextManagerListeners.remove(contextManagerListener);
237: }
238: }
239:
240: public void setEnabledContextIds(Set enabledContextIds) {
241: contextManager.setActiveContextIds(enabledContextIds);
242: }
243: }
|