KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > services > EvaluationAuthority


1 /*******************************************************************************
2  * Copyright (c) 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  ******************************************************************************/

11
12 package org.eclipse.ui.internal.services;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Arrays JavaDoc;
16 import java.util.Collection JavaDoc;
17 import java.util.HashMap JavaDoc;
18 import java.util.HashSet JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
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 /**
35  * @since 3.3
36  *
37  */

38 public class EvaluationAuthority extends ExpressionAuthority {
39
40     /**
41      *
42      */

43     private static final String JavaDoc COMPONENT = "EVALUATION"; //$NON-NLS-1$
44

45     /**
46      * A bucket sort of the evaluation references based on source priority. Each
47      * reference will appear only once per set, but may appear in multiple sets.
48      * If no references are defined for a particular priority level, then the
49      * array at that index will only contain <code>null</code>.
50      */

51     private final Map JavaDoc cachesBySourceName = new HashMap JavaDoc();
52     private ListenerList serviceListeners = new ListenerList();
53     private int notifying = 0;
54
55     // private final Map cachesByExpression = new HashMap();
56

57     public void addEvaluationListener(IEvaluationReference ref) {
58         // we update the source priority bucket sort of activations.
59
String JavaDoc[] sourceNames = getNames(ref);
60         for (int i = 0; i < sourceNames.length; i++) {
61             Map JavaDoc cachesByExpression = (HashMap JavaDoc) cachesBySourceName
62                     .get(sourceNames[i]);
63             if (cachesByExpression == null) {
64                 cachesByExpression = new HashMap JavaDoc(1);
65                 cachesBySourceName.put(sourceNames[i], cachesByExpression);
66             }
67             final Expression expression = ref.getExpression();
68             Set JavaDoc caches = (Set JavaDoc) cachesByExpression.get(expression);
69             if (caches == null) {
70                 caches = new HashSet JavaDoc();
71                 cachesByExpression.put(expression, caches);
72             }
73             caches.add(ref);
74         }
75
76         boolean result = evaluate(ref);
77         firePropertyChange(ref, null, new Boolean JavaDoc(result));
78     }
79
80     /**
81      * @param ref
82      * @return
83      */

84     private String JavaDoc[] getNames(IEvaluationReference ref) {
85         ExpressionInfo info = new ExpressionInfo();
86         ref.getExpression().collectExpressionInfo(info);
87         if (info.hasDefaultVariableAccess()) {
88             ArrayList JavaDoc l = new ArrayList JavaDoc(Arrays.asList(info
89                     .getAccessedVariableNames()));
90             l.add(ISources.ACTIVE_CURRENT_SELECTION_NAME);
91             return (String JavaDoc[]) l.toArray(new String JavaDoc[l.size()]);
92         }
93         return info.getAccessedVariableNames();
94     }
95
96     /*
97      * (non-Javadoc)
98      *
99      * @see org.eclipse.ui.internal.services.ExpressionAuthority#sourceChanged(int)
100      */

101     protected void sourceChanged(int sourcePriority) {
102         // no-op, we want the other one
103
}
104
105     /*
106      * (non-Javadoc)
107      *
108      * @see org.eclipse.ui.internal.services.ExpressionAuthority#sourceChanged(java.lang.String[])
109      */

110     protected void sourceChanged(String JavaDoc[] sourceNames) {
111         startSourceChange(sourceNames);
112         try {
113             // evaluations to recompute
114
for (int i = 0; i < sourceNames.length; i++) {
115                 Map JavaDoc cachesByExpression = (HashMap JavaDoc) cachesBySourceName
116                         .get(sourceNames[i]);
117                 if (cachesByExpression != null) {
118                     Collection JavaDoc v = cachesByExpression.values();
119                     Set JavaDoc[] expressionCaches = (Set JavaDoc[]) v
120                             .toArray(new Set JavaDoc[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     /**
137      * This will evaluate all refs with the same expression.
138      * @param refs
139      */

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 JavaDoc(oldValue),
154                     new Boolean JavaDoc(newValue));
155         }
156         for (k++; k < refs.length; k++) {
157             ref = refs[k];
158             // this is not as expensive as it looks
159
if (ref.isPostingChanges()) {
160                 oldValue = evaluate(ref);
161                 if (oldValue != newValue) {
162                     ref.setResult(newValue);
163                     firePropertyChange(ref, new Boolean JavaDoc(oldValue), new Boolean JavaDoc(
164                             newValue));
165                 }
166             }
167         }
168     }
169
170     /**
171      * @param sourceNames
172      */

173     private void startSourceChange(final String JavaDoc[] sourceNames) {
174         if (Policy.DEBUG_SOURCES) {
175             Tracing.printTrace(COMPONENT, "start source changed: " //$NON-NLS-1$
176
+ Arrays.asList(sourceNames));
177         }
178         notifying++;
179         if (notifying == 1) {
180             fireServiceChange(IEvaluationService.PROP_NOTIFYING, new Boolean JavaDoc(
181                     false), new Boolean JavaDoc(true));
182         }
183     }
184
185     /**
186      * @param sourceNames
187      */

188     private void endSourceChange(final String JavaDoc[] sourceNames) {
189         if (Policy.DEBUG_SOURCES) {
190             Tracing.printTrace(COMPONENT, "end source changed: " //$NON-NLS-1$
191
+ Arrays.asList(sourceNames));
192         }
193         if (notifying == 1) {
194             fireServiceChange(IEvaluationService.PROP_NOTIFYING, new Boolean JavaDoc(
195                     true), new Boolean JavaDoc(false));
196         }
197         notifying--;
198     }
199
200     /**
201      * @param ref
202      */

203     public void removeEvaluationListener(IEvaluationReference ref) {
204         // Next we update the source priority bucket sort of activations.
205
String JavaDoc[] sourceNames = getNames(ref);
206         for (int i = 0; i < sourceNames.length; i++) {
207             Map JavaDoc cachesByExpression = (HashMap JavaDoc) cachesBySourceName
208                     .get(sourceNames[i]);
209             if (cachesByExpression != null) {
210                 Set JavaDoc caches = (Set JavaDoc) 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 JavaDoc(result), null);
224     }
225
226     /**
227      * @param ref
228      * @param oldValue
229      * @param newValue
230      */

231     private void firePropertyChange(IEvaluationReference ref, Object JavaDoc oldValue,
232             Object JavaDoc newValue) {
233         ref.getListener().propertyChange(
234                 new PropertyChangeEvent(ref, ref.getProperty(), oldValue,
235                         newValue));
236     }
237
238     private void fireServiceChange(final String JavaDoc property,
239             final Object JavaDoc oldValue, final Object JavaDoc newValue) {
240         Object JavaDoc[] 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 JavaDoc exception) {
245                     WorkbenchPlugin.log(exception);
246                 }
247
248                 public void run() throws Exception JavaDoc {
249                     listener.propertyChange(new PropertyChangeEvent(
250                             EvaluationAuthority.this, property, oldValue,
251                             newValue));
252                 }
253             });
254         }
255     }
256
257     /**
258      * @param listener
259      */

260     public void addServiceListener(IPropertyChangeListener listener) {
261         serviceListeners.add(listener);
262     }
263
264     /**
265      * @param listener
266      */

267     public void removeServiceListener(IPropertyChangeListener listener) {
268         serviceListeners.remove(listener);
269     }
270 }
271
Popular Tags