1 11 12 package org.eclipse.ui.internal.contexts; 13 14 import java.util.ArrayList ; 15 import java.util.Collection ; 16 import java.util.Comparator ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Iterator ; 20 import java.util.Map ; 21 import java.util.Set ; 22 import java.util.SortedSet ; 23 import java.util.TreeMap ; 24 import java.util.TreeSet ; 25 import java.util.WeakHashMap ; 26 27 import org.eclipse.core.runtime.Platform; 28 import org.eclipse.ui.contexts.ContextEvent; 29 import org.eclipse.ui.contexts.ContextManagerEvent; 30 import org.eclipse.ui.contexts.IContext; 31 import org.eclipse.ui.contexts.NotDefinedException; 32 import org.eclipse.ui.internal.util.Util; 33 34 public final class MutableContextManager extends AbstractContextManager 35 implements IMutableContextManager { 36 37 45 private class ContextIdDepthComparator implements Comparator { 46 47 50 public final int compare(final Object object1, final Object object2) { 51 final String contextId1 = (String ) object1; 52 final String contextId2 = (String ) object2; 53 IContext context; 54 String parentId; 55 56 int depth1 = 0; 58 context = getContext(contextId1); 59 try { 60 parentId = context.getParentId(); 61 while (parentId != null) { 62 depth1++; 63 context = getContext(parentId); 64 parentId = context.getParentId(); 65 } 66 } catch (final NotDefinedException e) { 67 } 69 70 int depth2 = 0; 72 context = getContext(contextId2); 73 try { 74 parentId = context.getParentId(); 75 while (parentId != null) { 76 depth2++; 77 context = getContext(parentId); 78 parentId = context.getParentId(); 79 } 80 } catch (final NotDefinedException e) { 81 } 83 84 int compare = depth2 - depth1; 86 if (compare == 0) { 87 compare = contextId1.compareTo(contextId2); 88 } 89 90 return compare; 91 } 92 } 93 94 102 private class DepthSortedContextIdSet extends TreeSet { 103 104 113 private DepthSortedContextIdSet(final Set contextIds) { 114 super(new ContextIdDepthComparator()); 115 addAll(contextIds); 116 } 117 } 118 119 static boolean isContextDefinitionChildOf(String ancestor, String id, 120 Map contextDefinitionsById) { 121 Collection visited = new HashSet (); 122 123 while (id != null && !visited.contains(id)) { 124 ContextDefinition contextDefinition = (ContextDefinition) contextDefinitionsById 125 .get(id); 126 visited.add(id); 127 128 if (contextDefinition != null 129 && Util.equals(id = contextDefinition.getParentId(), 130 ancestor)) return true; 131 } 132 133 return false; 134 } 135 136 private Map contextContextBindingsByParentContextId = new HashMap (); 137 138 private Map contextDefinitionsById = new HashMap (); 139 140 private IContextRegistry contextRegistry; 141 142 private Map contextsById = new WeakHashMap (); 143 144 private Set definedContextIds = new HashSet (); 145 146 private Set enabledContextIds = new HashSet (); 147 148 public MutableContextManager() { 149 this(new ExtensionContextRegistry(Platform.getExtensionRegistry())); 150 } 151 152 public MutableContextManager(IContextRegistry contextRegistry) { 153 if (contextRegistry == null) throw new NullPointerException (); 154 155 this.contextRegistry = contextRegistry; 156 157 this.contextRegistry 158 .addContextRegistryListener(new IContextRegistryListener() { 159 160 public void contextRegistryChanged( 161 ContextRegistryEvent contextRegistryEvent) { 162 readRegistry(); 163 } 164 }); 165 166 readRegistry(); 167 } 168 169 public IContext getContext(String contextId) { 170 if (contextId == null) throw new NullPointerException (); 171 172 Context context = (Context) contextsById.get(contextId); 173 174 if (context == null) { 175 context = new Context(contextId); 176 updateContext(context); 177 contextsById.put(contextId, context); 178 } 179 180 return context; 181 } 182 183 public SortedSet getDefinedContextIds() { 184 return new DepthSortedContextIdSet(definedContextIds); 185 } 186 187 public SortedSet getEnabledContextIds() { 188 return new DepthSortedContextIdSet(enabledContextIds); 189 } 190 191 private void notifyContexts(Map contextEventsByContextId) { 192 for (Iterator iterator = contextEventsByContextId.entrySet().iterator(); iterator 193 .hasNext();) { 194 Map.Entry entry = (Map.Entry ) iterator.next(); 195 String contextId = (String ) entry.getKey(); 196 ContextEvent contextEvent = (ContextEvent) entry.getValue(); 197 Context context = (Context) contextsById.get(contextId); 198 199 if (context != null) context.fireContextChanged(contextEvent); 200 } 201 } 202 203 private void readRegistry() { 204 Collection contextDefinitions = new ArrayList (); 205 contextDefinitions.addAll(contextRegistry.getContextDefinitions()); 206 Map contextDefinitionsById = new HashMap (ContextDefinition 207 .contextDefinitionsById(contextDefinitions, false)); 208 209 for (Iterator iterator = contextDefinitionsById.values().iterator(); iterator 210 .hasNext();) { 211 ContextDefinition contextDefinition = (ContextDefinition) iterator 212 .next(); 213 String name = contextDefinition.getName(); 214 215 if (name == null || name.length() == 0) iterator.remove(); 216 } 217 218 for (Iterator iterator = contextDefinitionsById.keySet().iterator(); iterator 219 .hasNext();) 220 if (!isContextDefinitionChildOf(null, (String ) iterator.next(), 221 contextDefinitionsById)) iterator.remove(); 222 this.contextDefinitionsById = contextDefinitionsById; 223 boolean definedContextIdsChanged = false; 224 Set definedContextIds = new HashSet (contextDefinitionsById.keySet()); 225 Set previouslyDefinedContextIds = null; 226 227 if (!definedContextIds.equals(this.definedContextIds)) { 228 previouslyDefinedContextIds = this.definedContextIds; 229 this.definedContextIds = definedContextIds; 230 definedContextIdsChanged = true; 231 } 232 233 Map contextEventsByContextId = updateContexts(contextsById.keySet()); 234 235 if (definedContextIdsChanged) 236 fireContextManagerChanged(new ContextManagerEvent(this, 237 definedContextIdsChanged, false, 238 previouslyDefinedContextIds, null)); 239 240 if (contextEventsByContextId != null) 241 notifyContexts(contextEventsByContextId); 242 } 243 244 public void setEnabledContextIds(Set enabledContextIds) { 245 enabledContextIds = Util.safeCopy(enabledContextIds, String .class); 246 boolean contextManagerChanged = false; 247 Map contextEventsByContextId = null; 248 Set previouslyEnabledContextIds = null; 249 250 if (!this.enabledContextIds.equals(enabledContextIds)) { 251 previouslyEnabledContextIds = this.enabledContextIds; 252 this.enabledContextIds = enabledContextIds; 253 contextManagerChanged = true; 254 contextEventsByContextId = updateContexts(contextsById.keySet()); 255 } 256 257 if (contextEventsByContextId != null) 258 notifyContexts(contextEventsByContextId); 259 260 if (contextManagerChanged) 261 fireContextManagerChanged(new ContextManagerEvent(this, false, 262 true, null, previouslyEnabledContextIds)); 263 } 264 265 private ContextEvent updateContext(Context context) { 266 Set contextContextBindings = (Set ) contextContextBindingsByParentContextId 267 .get(context.getId()); 268 ContextDefinition contextDefinition = (ContextDefinition) contextDefinitionsById 269 .get(context.getId()); 270 boolean definedChanged = context.setDefined(contextDefinition != null); 271 boolean enabledChanged = context.setEnabled(enabledContextIds 272 .contains(context.getId())); 273 boolean nameChanged = context 274 .setName(contextDefinition != null ? contextDefinition 275 .getName() : null); 276 boolean parentIdChanged = context 277 .setParentId(contextDefinition != null ? contextDefinition 278 .getParentId() : null); 279 280 if (definedChanged || enabledChanged || nameChanged || parentIdChanged) 281 return new ContextEvent(context, definedChanged, enabledChanged, 282 nameChanged, parentIdChanged); 283 else 284 return null; 285 } 286 287 private Map updateContexts(Collection contextIds) { 288 Map contextEventsByContextId = new TreeMap (); 289 290 for (Iterator iterator = contextIds.iterator(); iterator.hasNext();) { 291 String contextId = (String ) iterator.next(); 292 Context context = (Context) contextsById.get(contextId); 293 294 if (context != null) { 295 ContextEvent contextEvent = updateContext(context); 296 297 if (contextEvent != null) 298 contextEventsByContextId.put(contextId, contextEvent); 299 } 300 } 301 302 return contextEventsByContextId; 303 } 304 } 305 | Popular Tags |