1 | /* |
2 | *Copyright 2006 SDQ Research Group, University of Karlsruhe (TH) |
3 | */ |
4 | package de.uka.ipd.sdq.pcm.gmf.seff.providers; |
5 | |
6 | import java.util.ArrayList; |
7 | import java.util.HashMap; |
8 | import java.util.Iterator; |
9 | import java.util.List; |
10 | import java.util.Map; |
11 | |
12 | import org.eclipse.core.resources.IFile; |
13 | import org.eclipse.core.resources.IMarker; |
14 | import org.eclipse.core.resources.IResource; |
15 | import org.eclipse.core.runtime.CoreException; |
16 | import org.eclipse.draw2d.FlowLayout; |
17 | import org.eclipse.draw2d.Label; |
18 | import org.eclipse.emf.transaction.util.TransactionUtil; |
19 | import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; |
20 | import org.eclipse.gef.EditDomain; |
21 | import org.eclipse.gef.EditPart; |
22 | import org.eclipse.gef.GraphicalEditPart; |
23 | import org.eclipse.gef.editparts.AbstractConnectionEditPart; |
24 | import org.eclipse.gmf.runtime.common.core.service.AbstractProvider; |
25 | import org.eclipse.gmf.runtime.common.core.service.IOperation; |
26 | import org.eclipse.gmf.runtime.common.ui.resources.FileChangeManager; |
27 | import org.eclipse.gmf.runtime.common.ui.resources.IFileObserver; |
28 | import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; |
29 | import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditDomain; |
30 | import org.eclipse.gmf.runtime.diagram.ui.services.decorator.AbstractDecorator; |
31 | import org.eclipse.gmf.runtime.diagram.ui.services.decorator.CreateDecoratorsOperation; |
32 | import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecorator; |
33 | import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorProvider; |
34 | import org.eclipse.gmf.runtime.diagram.ui.services.decorator.IDecoratorTarget; |
35 | import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil; |
36 | import org.eclipse.gmf.runtime.notation.Diagram; |
37 | import org.eclipse.gmf.runtime.notation.Edge; |
38 | import org.eclipse.gmf.runtime.notation.View; |
39 | import org.eclipse.swt.graphics.Image; |
40 | import org.eclipse.ui.ISharedImages; |
41 | import org.eclipse.ui.PlatformUI; |
42 | |
43 | import de.uka.ipd.sdq.pcm.gmf.seff.edit.parts.ResourceDemandingSEFFEditPart; |
44 | import de.uka.ipd.sdq.pcm.gmf.seff.part.PalladioComponentModelSeffDiagramEditorPlugin; |
45 | import de.uka.ipd.sdq.pcm.gmf.seff.part.PalladioComponentModelVisualIDRegistry; |
46 | import de.uka.ipd.sdq.pcm.gmf.seff.part.SeffDiagramEditor; |
47 | |
48 | /** |
49 | * @generated |
50 | */ |
51 | public class PalladioComponentModelValidationDecoratorProvider extends |
52 | AbstractProvider implements IDecoratorProvider { |
53 | /** |
54 | * @generated |
55 | */ |
56 | private static final String KEY = "validationStatus"; //$NON-NLS-1$ |
57 | /** |
58 | * @generated |
59 | */ |
60 | private static final String MARKER_TYPE = PalladioComponentModelSeffDiagramEditorPlugin.ID |
61 | + ".diagnostic"; //$NON-NLS-1$ //$NON-NLS-2$ |
62 | /** |
63 | * @generated |
64 | */ |
65 | private static MarkerObserver fileObserver; |
66 | |
67 | /** |
68 | * @generated |
69 | */ |
70 | private static Map/*<String, List<IDecorator>>*/allDecorators = new HashMap(); |
71 | |
72 | /** |
73 | * @generated |
74 | */ |
75 | public void createDecorators(IDecoratorTarget decoratorTarget) { |
76 | EditPart editPart = (EditPart) decoratorTarget |
77 | .getAdapter(EditPart.class); |
78 | if (editPart instanceof org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart |
79 | || editPart instanceof AbstractConnectionEditPart) { |
80 | Object model = editPart.getModel(); |
81 | if ((model instanceof View)) { |
82 | View view = (View) model; |
83 | if (!(view instanceof Edge) && !view.isSetElement()) { |
84 | return; |
85 | } |
86 | } |
87 | EditDomain ed = editPart.getViewer().getEditDomain(); |
88 | if (!(ed instanceof DiagramEditDomain)) { |
89 | return; |
90 | } |
91 | if (((DiagramEditDomain) ed).getEditorPart() instanceof SeffDiagramEditor) { |
92 | decoratorTarget.installDecorator(KEY, new StatusDecorator( |
93 | decoratorTarget)); |
94 | } |
95 | } |
96 | } |
97 | |
98 | /** |
99 | * @generated |
100 | */ |
101 | public boolean provides(IOperation operation) { |
102 | if (!(operation instanceof CreateDecoratorsOperation)) { |
103 | return false; |
104 | } |
105 | IDecoratorTarget decoratorTarget = ((CreateDecoratorsOperation) operation) |
106 | .getDecoratorTarget(); |
107 | View view = (View) decoratorTarget.getAdapter(View.class); |
108 | return view != null |
109 | && ResourceDemandingSEFFEditPart.MODEL_ID |
110 | .equals(PalladioComponentModelVisualIDRegistry |
111 | .getModelID(view)); |
112 | } |
113 | |
114 | /** |
115 | * @generated |
116 | */ |
117 | public static void refreshDecorators(View view) { |
118 | refreshDecorators(ViewUtil.getIdStr(view), view.getDiagram()); |
119 | } |
120 | |
121 | /** |
122 | * @generated |
123 | */ |
124 | private static void refreshDecorators(String viewId, Diagram diagram) { |
125 | final List decorators = viewId != null ? (List) allDecorators |
126 | .get(viewId) : null; |
127 | if (decorators == null || decorators.isEmpty() || diagram == null) { |
128 | return; |
129 | } |
130 | final Diagram fdiagram = diagram; |
131 | PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
132 | |
133 | public void run() { |
134 | try { |
135 | TransactionUtil.getEditingDomain(fdiagram).runExclusive( |
136 | new Runnable() { |
137 | |
138 | public void run() { |
139 | for (Iterator it = decorators.iterator(); it |
140 | .hasNext();) { |
141 | IDecorator decorator = (IDecorator) it |
142 | .next(); |
143 | decorator.refresh(); |
144 | } |
145 | } |
146 | }); |
147 | } catch (Exception e) { |
148 | PalladioComponentModelSeffDiagramEditorPlugin.getInstance() |
149 | .logError("Decorator refresh failure", e); //$NON-NLS-1$ |
150 | } |
151 | } |
152 | }); |
153 | } |
154 | |
155 | /** |
156 | * @generated |
157 | */ |
158 | public static class StatusDecorator extends AbstractDecorator { |
159 | /** |
160 | * @generated |
161 | */ |
162 | private String viewId; |
163 | |
164 | /** |
165 | * @generated |
166 | */ |
167 | public StatusDecorator(IDecoratorTarget decoratorTarget) { |
168 | super(decoratorTarget); |
169 | try { |
170 | final View view = (View) getDecoratorTarget().getAdapter( |
171 | View.class); |
172 | TransactionUtil.getEditingDomain(view).runExclusive( |
173 | new Runnable() { |
174 | |
175 | public void run() { |
176 | StatusDecorator.this.viewId = view != null ? ViewUtil |
177 | .getIdStr(view) |
178 | : null; |
179 | } |
180 | }); |
181 | } catch (Exception e) { |
182 | PalladioComponentModelSeffDiagramEditorPlugin.getInstance() |
183 | .logError("ViewID access failure", e); //$NON-NLS-1$ |
184 | } |
185 | } |
186 | |
187 | /** |
188 | * @generated |
189 | */ |
190 | public void refresh() { |
191 | removeDecoration(); |
192 | View view = (View) getDecoratorTarget().getAdapter(View.class); |
193 | if (view == null || view.eResource() == null) { |
194 | return; |
195 | } |
196 | EditPart editPart = (EditPart) getDecoratorTarget().getAdapter( |
197 | EditPart.class); |
198 | if (editPart == null || editPart.getViewer() == null) { |
199 | return; |
200 | } |
201 | |
202 | // query for all the validation markers of the current resource |
203 | String elementId = ViewUtil.getIdStr(view); |
204 | if (elementId == null) { |
205 | return; |
206 | } |
207 | int severity = IMarker.SEVERITY_INFO; |
208 | IMarker foundMarker = null; |
209 | IResource resource = WorkspaceSynchronizer |
210 | .getFile(view.eResource()); |
211 | if (resource == null || !resource.exists()) { |
212 | return; |
213 | } |
214 | IMarker[] markers = null; |
215 | try { |
216 | markers = resource.findMarkers(MARKER_TYPE, true, |
217 | IResource.DEPTH_INFINITE); |
218 | } catch (CoreException e) { |
219 | PalladioComponentModelSeffDiagramEditorPlugin.getInstance() |
220 | .logError("Validation markers refresh failure", e); //$NON-NLS-1$ |
221 | } |
222 | if (markers == null || markers.length == 0) { |
223 | return; |
224 | } |
225 | Label toolTip = null; |
226 | for (int i = 0; i < markers.length; i++) { |
227 | IMarker marker = markers[i]; |
228 | String attribute = marker |
229 | .getAttribute( |
230 | org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID, |
231 | ""); //$NON-NLS-1$ |
232 | if (attribute.equals(elementId)) { |
233 | int nextSeverity = marker.getAttribute(IMarker.SEVERITY, |
234 | IMarker.SEVERITY_INFO); |
235 | Image nextImage = getImage(nextSeverity); |
236 | if (foundMarker == null) { |
237 | foundMarker = marker; |
238 | toolTip = new Label(marker.getAttribute( |
239 | IMarker.MESSAGE, ""), //$NON-NLS-1$ |
240 | nextImage); |
241 | } else { |
242 | if (toolTip.getChildren().isEmpty()) { |
243 | Label comositeLabel = new Label(); |
244 | FlowLayout fl = new FlowLayout(false); |
245 | fl.setMinorSpacing(0); |
246 | comositeLabel.setLayoutManager(fl); |
247 | comositeLabel.add(toolTip); |
248 | toolTip = comositeLabel; |
249 | } |
250 | toolTip.add(new Label(marker.getAttribute( |
251 | IMarker.MESSAGE, ""), //$NON-NLS-1$ |
252 | nextImage)); |
253 | } |
254 | severity = (nextSeverity > severity) ? nextSeverity |
255 | : severity; |
256 | } |
257 | } |
258 | if (foundMarker == null) { |
259 | return; |
260 | } |
261 | |
262 | // add decoration |
263 | if (editPart instanceof GraphicalEditPart) { |
264 | if (view instanceof Edge) { |
265 | setDecoration(getDecoratorTarget().addConnectionDecoration( |
266 | getImage(severity), 50, true)); |
267 | } else { |
268 | int margin = -1; |
269 | if (editPart instanceof GraphicalEditPart) { |
270 | margin = MapModeUtil.getMapMode( |
271 | ((GraphicalEditPart) editPart).getFigure()) |
272 | .DPtoLP(margin); |
273 | } |
274 | setDecoration(getDecoratorTarget() |
275 | .addShapeDecoration(getImage(severity), |
276 | IDecoratorTarget.Direction.NORTH_EAST, |
277 | margin, true)); |
278 | } |
279 | getDecoration().setToolTip(toolTip); |
280 | } |
281 | } |
282 | |
283 | /** |
284 | * @generated |
285 | */ |
286 | private Image getImage(int severity) { |
287 | String imageName = ISharedImages.IMG_OBJS_ERROR_TSK; |
288 | switch (severity) { |
289 | case IMarker.SEVERITY_ERROR: |
290 | imageName = ISharedImages.IMG_OBJS_ERROR_TSK; |
291 | break; |
292 | case IMarker.SEVERITY_WARNING: |
293 | imageName = ISharedImages.IMG_OBJS_WARN_TSK; |
294 | break; |
295 | default: |
296 | imageName = ISharedImages.IMG_OBJS_INFO_TSK; |
297 | } |
298 | return PlatformUI.getWorkbench().getSharedImages().getImage( |
299 | imageName); |
300 | } |
301 | |
302 | /** |
303 | * @generated |
304 | */ |
305 | public void activate() { |
306 | if (viewId == null) { |
307 | return; |
308 | } |
309 | |
310 | // add self to global decorators registry |
311 | List list = (List) allDecorators.get(viewId); |
312 | if (list == null) { |
313 | list = new ArrayList(2); |
314 | list.add(this); |
315 | allDecorators.put(viewId, list); |
316 | } else if (!list.contains(this)) { |
317 | list.add(this); |
318 | } |
319 | |
320 | // start listening to changes in resources |
321 | View view = (View) getDecoratorTarget().getAdapter(View.class); |
322 | if (view == null) { |
323 | return; |
324 | } |
325 | Diagram diagramView = view.getDiagram(); |
326 | if (diagramView == null) { |
327 | return; |
328 | } |
329 | if (fileObserver == null) { |
330 | FileChangeManager.getInstance().addFileObserver( |
331 | fileObserver = new MarkerObserver(diagramView)); |
332 | } |
333 | } |
334 | |
335 | /** |
336 | * @generated |
337 | */ |
338 | public void deactivate() { |
339 | if (viewId == null) { |
340 | return; |
341 | } |
342 | |
343 | // remove self from global decorators registry |
344 | List list = (List) allDecorators.get(viewId); |
345 | if (list != null) { |
346 | list.remove(this); |
347 | if (list.isEmpty()) { |
348 | allDecorators.remove(viewId); |
349 | } |
350 | } |
351 | |
352 | // stop listening to changes in resources if there are no more decorators |
353 | if (fileObserver != null && allDecorators.isEmpty()) { |
354 | FileChangeManager.getInstance() |
355 | .removeFileObserver(fileObserver); |
356 | fileObserver = null; |
357 | } |
358 | super.deactivate(); |
359 | } |
360 | } |
361 | |
362 | /** |
363 | * @generated |
364 | */ |
365 | static class MarkerObserver implements IFileObserver { |
366 | /** |
367 | * @generated |
368 | */ |
369 | private Diagram diagram; |
370 | |
371 | /** |
372 | * @generated |
373 | */ |
374 | private MarkerObserver(Diagram diagram) { |
375 | this.diagram = diagram; |
376 | } |
377 | |
378 | /** |
379 | * @generated |
380 | */ |
381 | public void handleFileRenamed(IFile oldFile, IFile file) { |
382 | } |
383 | |
384 | /** |
385 | * @generated |
386 | */ |
387 | public void handleFileMoved(IFile oldFile, IFile file) { |
388 | } |
389 | |
390 | /** |
391 | * @generated |
392 | */ |
393 | public void handleFileDeleted(IFile file) { |
394 | } |
395 | |
396 | /** |
397 | * @generated |
398 | */ |
399 | public void handleFileChanged(IFile file) { |
400 | } |
401 | |
402 | /** |
403 | * @generated |
404 | */ |
405 | public void handleMarkerAdded(IMarker marker) { |
406 | if (marker |
407 | .getAttribute( |
408 | org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID, |
409 | null) != null) { |
410 | handleMarkerChanged(marker); |
411 | } |
412 | } |
413 | |
414 | /** |
415 | * @generated |
416 | */ |
417 | public void handleMarkerDeleted(IMarker marker, Map attributes) { |
418 | String viewId = (String) attributes |
419 | .get(org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID); |
420 | refreshDecorators(viewId, diagram); |
421 | } |
422 | |
423 | /** |
424 | * @generated |
425 | */ |
426 | public void handleMarkerChanged(IMarker marker) { |
427 | if (!MARKER_TYPE.equals(getType(marker))) { |
428 | return; |
429 | } |
430 | String viewId = marker |
431 | .getAttribute( |
432 | org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID, |
433 | ""); //$NON-NLS-1$ |
434 | refreshDecorators(viewId, diagram); |
435 | } |
436 | |
437 | /** |
438 | * @generated |
439 | */ |
440 | private String getType(IMarker marker) { |
441 | try { |
442 | return marker.getType(); |
443 | } catch (CoreException e) { |
444 | PalladioComponentModelSeffDiagramEditorPlugin.getInstance() |
445 | .logError("Validation marker refresh failure", e); //$NON-NLS-1$ |
446 | return ""; //$NON-NLS-1$ |
447 | } |
448 | } |
449 | } |
450 | } |