1 11 12 package org.eclipse.ui.internal.services; 13 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.Collection ; 17 import java.util.HashMap ; 18 import java.util.HashSet ; 19 import java.util.Map ; 20 import java.util.Set ; 21 22 import org.eclipse.core.commands.util.Tracing; 23 import org.eclipse.core.expressions.Expression; 24 import org.eclipse.core.expressions.ExpressionInfo; 25 import org.eclipse.core.runtime.ISafeRunnable; 26 import org.eclipse.core.runtime.ListenerList; 27 import org.eclipse.core.runtime.SafeRunner; 28 import org.eclipse.jface.util.IPropertyChangeListener; 29 import org.eclipse.jface.util.PropertyChangeEvent; 30 import org.eclipse.ui.ISources; 31 import org.eclipse.ui.internal.WorkbenchPlugin; 32 import org.eclipse.ui.internal.misc.Policy; 33 34 38 public class EvaluationAuthority extends ExpressionAuthority { 39 40 43 private static final String COMPONENT = "EVALUATION"; 45 51 private final Map cachesBySourceName = new HashMap (); 52 private ListenerList serviceListeners = new ListenerList(); 53 private int notifying = 0; 54 55 57 public void addEvaluationListener(IEvaluationReference ref) { 58 String [] sourceNames = getNames(ref); 60 for (int i = 0; i < sourceNames.length; i++) { 61 Map cachesByExpression = (HashMap ) cachesBySourceName 62 .get(sourceNames[i]); 63 if (cachesByExpression == null) { 64 cachesByExpression = new HashMap (1); 65 cachesBySourceName.put(sourceNames[i], cachesByExpression); 66 } 67 final Expression expression = ref.getExpression(); 68 Set caches = (Set ) cachesByExpression.get(expression); 69 if (caches == null) { 70 caches = new HashSet (); 71 cachesByExpression.put(expression, caches); 72 } 73 caches.add(ref); 74 } 75 76 boolean result = evaluate(ref); 77 firePropertyChange(ref, null, new Boolean (result)); 78 } 79 80 84 private String [] getNames(IEvaluationReference ref) { 85 ExpressionInfo info = new ExpressionInfo(); 86 ref.getExpression().collectExpressionInfo(info); 87 if (info.hasDefaultVariableAccess()) { 88 ArrayList l = new ArrayList (Arrays.asList(info 89 .getAccessedVariableNames())); 90 l.add(ISources.ACTIVE_CURRENT_SELECTION_NAME); 91 return (String []) l.toArray(new String [l.size()]); 92 } 93 return info.getAccessedVariableNames(); 94 } 95 96 101 protected void sourceChanged(int sourcePriority) { 102 } 104 105 110 protected void sourceChanged(String [] sourceNames) { 111 startSourceChange(sourceNames); 112 try { 113 for (int i = 0; i < sourceNames.length; i++) { 115 Map cachesByExpression = (HashMap ) cachesBySourceName 116 .get(sourceNames[i]); 117 if (cachesByExpression != null) { 118 Collection v = cachesByExpression.values(); 119 Set [] expressionCaches = (Set []) v 120 .toArray(new Set [v.size()]); 121 for (int j = 0; j < expressionCaches.length; j++) { 122 if (expressionCaches[j].size() > 0) { 123 IEvaluationReference[] refs = (IEvaluationReference[]) expressionCaches[j] 124 .toArray(new IEvaluationReference[expressionCaches[j] 125 .size()]); 126 refsWithSameExpression(refs); 127 } 128 } 129 } 130 } 131 } finally { 132 endSourceChange(sourceNames); 133 } 134 } 135 136 140 private void refsWithSameExpression(IEvaluationReference[] refs) { 141 int k=0; 142 while (k<refs.length && !refs[k].isPostingChanges()) { 143 k++; 144 } 145 if (k>=refs.length) { 146 return; 147 } 148 IEvaluationReference ref = refs[k]; 149 boolean oldValue = evaluate(ref); 150 ref.clearResult(); 151 final boolean newValue = evaluate(ref); 152 if (oldValue != newValue) { 153 firePropertyChange(ref, new Boolean (oldValue), 154 new Boolean (newValue)); 155 } 156 for (k++; k < refs.length; k++) { 157 ref = refs[k]; 158 if (ref.isPostingChanges()) { 160 oldValue = evaluate(ref); 161 if (oldValue != newValue) { 162 ref.setResult(newValue); 163 firePropertyChange(ref, new Boolean (oldValue), new Boolean ( 164 newValue)); 165 } 166 } 167 } 168 } 169 170 173 private void startSourceChange(final String [] sourceNames) { 174 if (Policy.DEBUG_SOURCES) { 175 Tracing.printTrace(COMPONENT, "start source changed: " + Arrays.asList(sourceNames)); 177 } 178 notifying++; 179 if (notifying == 1) { 180 fireServiceChange(IEvaluationService.PROP_NOTIFYING, new Boolean ( 181 false), new Boolean (true)); 182 } 183 } 184 185 188 private void endSourceChange(final String [] sourceNames) { 189 if (Policy.DEBUG_SOURCES) { 190 Tracing.printTrace(COMPONENT, "end source changed: " + Arrays.asList(sourceNames)); 192 } 193 if (notifying == 1) { 194 fireServiceChange(IEvaluationService.PROP_NOTIFYING, new Boolean ( 195 true), new Boolean (false)); 196 } 197 notifying--; 198 } 199 200 203 public void removeEvaluationListener(IEvaluationReference ref) { 204 String [] sourceNames = getNames(ref); 206 for (int i = 0; i < sourceNames.length; i++) { 207 Map cachesByExpression = (HashMap ) cachesBySourceName 208 .get(sourceNames[i]); 209 if (cachesByExpression != null) { 210 Set caches = (Set ) cachesByExpression.get(ref.getExpression()); 211 if (caches != null) { 212 caches.remove(ref); 213 if (caches.isEmpty()) { 214 cachesByExpression.remove(ref.getExpression()); 215 } 216 } 217 if (cachesByExpression.isEmpty()) { 218 cachesBySourceName.remove(sourceNames[i]); 219 } 220 } 221 } 222 boolean result = evaluate(ref); 223 firePropertyChange(ref, new Boolean (result), null); 224 } 225 226 231 private void firePropertyChange(IEvaluationReference ref, Object oldValue, 232 Object newValue) { 233 ref.getListener().propertyChange( 234 new PropertyChangeEvent(ref, ref.getProperty(), oldValue, 235 newValue)); 236 } 237 238 private void fireServiceChange(final String property, 239 final Object oldValue, final Object newValue) { 240 Object [] listeners = serviceListeners.getListeners(); 241 for (int i = 0; i < listeners.length; i++) { 242 final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i]; 243 SafeRunner.run(new ISafeRunnable() { 244 public void handleException(Throwable exception) { 245 WorkbenchPlugin.log(exception); 246 } 247 248 public void run() throws Exception { 249 listener.propertyChange(new PropertyChangeEvent( 250 EvaluationAuthority.this, property, oldValue, 251 newValue)); 252 } 253 }); 254 } 255 } 256 257 260 public void addServiceListener(IPropertyChangeListener listener) { 261 serviceListeners.add(listener); 262 } 263 264 267 public void removeServiceListener(IPropertyChangeListener listener) { 268 serviceListeners.remove(listener); 269 } 270 } 271 | Popular Tags |