1 | /* |
2 | *Copyright 2007, IPD, SDQ, University of Karlsruhe |
3 | */ |
4 | package de.uka.ipd.sdq.pcm.gmf.repository.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.repository.edit.parts.RepositoryEditPart; |
44 | import de.uka.ipd.sdq.pcm.gmf.repository.part.PalladioComponentModelRepositoryDiagramEditor; |
45 | import de.uka.ipd.sdq.pcm.gmf.repository.part.PalladioComponentModelRepositoryDiagramEditorPlugin; |
46 | import de.uka.ipd.sdq.pcm.gmf.repository.part.PalladioComponentModelVisualIDRegistry; |
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 = PalladioComponentModelRepositoryDiagramEditorPlugin.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 PalladioComponentModelRepositoryDiagramEditor) { |
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 | && RepositoryEditPart.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 | PalladioComponentModelRepositoryDiagramEditorPlugin |
149 | .getInstance().logError( |
150 | "Decorator refresh failure", e); //$NON-NLS-1$ |
151 | } |
152 | } |
153 | }); |
154 | } |
155 | |
156 | /** |
157 | * @generated |
158 | */ |
159 | public static class StatusDecorator extends AbstractDecorator { |
160 | /** |
161 | * @generated |
162 | */ |
163 | private String viewId; |
164 | |
165 | /** |
166 | * @generated |
167 | */ |
168 | public StatusDecorator(IDecoratorTarget decoratorTarget) { |
169 | super(decoratorTarget); |
170 | try { |
171 | final View view = (View) getDecoratorTarget().getAdapter( |
172 | View.class); |
173 | TransactionUtil.getEditingDomain(view).runExclusive( |
174 | new Runnable() { |
175 | |
176 | public void run() { |
177 | StatusDecorator.this.viewId = view != null ? ViewUtil |
178 | .getIdStr(view) |
179 | : null; |
180 | } |
181 | }); |
182 | } catch (Exception e) { |
183 | PalladioComponentModelRepositoryDiagramEditorPlugin |
184 | .getInstance().logError("ViewID access failure", e); //$NON-NLS-1$ |
185 | } |
186 | } |
187 | |
188 | /** |
189 | * @generated |
190 | */ |
191 | public void refresh() { |
192 | removeDecoration(); |
193 | View view = (View) getDecoratorTarget().getAdapter(View.class); |
194 | if (view == null || view.eResource() == null) { |
195 | return; |
196 | } |
197 | EditPart editPart = (EditPart) getDecoratorTarget().getAdapter( |
198 | EditPart.class); |
199 | if (editPart == null || editPart.getViewer() == null) { |
200 | return; |
201 | } |
202 | |
203 | // query for all the validation markers of the current resource |
204 | String elementId = ViewUtil.getIdStr(view); |
205 | if (elementId == null) { |
206 | return; |
207 | } |
208 | int severity = IMarker.SEVERITY_INFO; |
209 | IMarker foundMarker = null; |
210 | IResource resource = WorkspaceSynchronizer |
211 | .getFile(view.eResource()); |
212 | if (resource == null || !resource.exists()) { |
213 | return; |
214 | } |
215 | IMarker[] markers = null; |
216 | try { |
217 | markers = resource.findMarkers(MARKER_TYPE, true, |
218 | IResource.DEPTH_INFINITE); |
219 | } catch (CoreException e) { |
220 | PalladioComponentModelRepositoryDiagramEditorPlugin |
221 | .getInstance().logError( |
222 | "Validation markers refresh failure", e); //$NON-NLS-1$ |
223 | } |
224 | if (markers == null || markers.length == 0) { |
225 | return; |
226 | } |
227 | Label toolTip = null; |
228 | for (int i = 0; i < markers.length; i++) { |
229 | IMarker marker = markers[i]; |
230 | String attribute = marker |
231 | .getAttribute( |
232 | org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID, |
233 | ""); //$NON-NLS-1$ |
234 | if (attribute.equals(elementId)) { |
235 | int nextSeverity = marker.getAttribute(IMarker.SEVERITY, |
236 | IMarker.SEVERITY_INFO); |
237 | Image nextImage = getImage(nextSeverity); |
238 | if (foundMarker == null) { |
239 | foundMarker = marker; |
240 | toolTip = new Label(marker.getAttribute( |
241 | IMarker.MESSAGE, ""), //$NON-NLS-1$ |
242 | nextImage); |
243 | } else { |
244 | if (toolTip.getChildren().isEmpty()) { |
245 | Label comositeLabel = new Label(); |
246 | FlowLayout fl = new FlowLayout(false); |
247 | fl.setMinorSpacing(0); |
248 | comositeLabel.setLayoutManager(fl); |
249 | comositeLabel.add(toolTip); |
250 | toolTip = comositeLabel; |
251 | } |
252 | toolTip.add(new Label(marker.getAttribute( |
253 | IMarker.MESSAGE, ""), //$NON-NLS-1$ |
254 | nextImage)); |
255 | } |
256 | severity = (nextSeverity > severity) ? nextSeverity |
257 | : severity; |
258 | } |
259 | } |
260 | if (foundMarker == null) { |
261 | return; |
262 | } |
263 | |
264 | // add decoration |
265 | if (editPart instanceof GraphicalEditPart) { |
266 | if (view instanceof Edge) { |
267 | setDecoration(getDecoratorTarget().addConnectionDecoration( |
268 | getImage(severity), 50, true)); |
269 | } else { |
270 | int margin = -1; |
271 | if (editPart instanceof GraphicalEditPart) { |
272 | margin = MapModeUtil.getMapMode( |
273 | ((GraphicalEditPart) editPart).getFigure()) |
274 | .DPtoLP(margin); |
275 | } |
276 | setDecoration(getDecoratorTarget() |
277 | .addShapeDecoration(getImage(severity), |
278 | IDecoratorTarget.Direction.NORTH_EAST, |
279 | margin, true)); |
280 | } |
281 | getDecoration().setToolTip(toolTip); |
282 | } |
283 | } |
284 | |
285 | /** |
286 | * @generated |
287 | */ |
288 | private Image getImage(int severity) { |
289 | String imageName = ISharedImages.IMG_OBJS_ERROR_TSK; |
290 | switch (severity) { |
291 | case IMarker.SEVERITY_ERROR: |
292 | imageName = ISharedImages.IMG_OBJS_ERROR_TSK; |
293 | break; |
294 | case IMarker.SEVERITY_WARNING: |
295 | imageName = ISharedImages.IMG_OBJS_WARN_TSK; |
296 | break; |
297 | default: |
298 | imageName = ISharedImages.IMG_OBJS_INFO_TSK; |
299 | } |
300 | return PlatformUI.getWorkbench().getSharedImages().getImage( |
301 | imageName); |
302 | } |
303 | |
304 | /** |
305 | * @generated |
306 | */ |
307 | public void activate() { |
308 | if (viewId == null) { |
309 | return; |
310 | } |
311 | |
312 | // add self to global decorators registry |
313 | List list = (List) allDecorators.get(viewId); |
314 | if (list == null) { |
315 | list = new ArrayList(2); |
316 | list.add(this); |
317 | allDecorators.put(viewId, list); |
318 | } else if (!list.contains(this)) { |
319 | list.add(this); |
320 | } |
321 | |
322 | // start listening to changes in resources |
323 | View view = (View) getDecoratorTarget().getAdapter(View.class); |
324 | if (view == null) { |
325 | return; |
326 | } |
327 | Diagram diagramView = view.getDiagram(); |
328 | if (diagramView == null) { |
329 | return; |
330 | } |
331 | if (fileObserver == null) { |
332 | FileChangeManager.getInstance().addFileObserver( |
333 | fileObserver = new MarkerObserver(diagramView)); |
334 | } |
335 | } |
336 | |
337 | /** |
338 | * @generated |
339 | */ |
340 | public void deactivate() { |
341 | if (viewId == null) { |
342 | return; |
343 | } |
344 | |
345 | // remove self from global decorators registry |
346 | List list = (List) allDecorators.get(viewId); |
347 | if (list != null) { |
348 | list.remove(this); |
349 | if (list.isEmpty()) { |
350 | allDecorators.remove(viewId); |
351 | } |
352 | } |
353 | |
354 | // stop listening to changes in resources if there are no more decorators |
355 | if (fileObserver != null && allDecorators.isEmpty()) { |
356 | FileChangeManager.getInstance() |
357 | .removeFileObserver(fileObserver); |
358 | fileObserver = null; |
359 | } |
360 | super.deactivate(); |
361 | } |
362 | } |
363 | |
364 | /** |
365 | * @generated |
366 | */ |
367 | static class MarkerObserver implements IFileObserver { |
368 | /** |
369 | * @generated |
370 | */ |
371 | private Diagram diagram; |
372 | |
373 | /** |
374 | * @generated |
375 | */ |
376 | private MarkerObserver(Diagram diagram) { |
377 | this.diagram = diagram; |
378 | } |
379 | |
380 | /** |
381 | * @generated |
382 | */ |
383 | public void handleFileRenamed(IFile oldFile, IFile file) { |
384 | } |
385 | |
386 | /** |
387 | * @generated |
388 | */ |
389 | public void handleFileMoved(IFile oldFile, IFile file) { |
390 | } |
391 | |
392 | /** |
393 | * @generated |
394 | */ |
395 | public void handleFileDeleted(IFile file) { |
396 | } |
397 | |
398 | /** |
399 | * @generated |
400 | */ |
401 | public void handleFileChanged(IFile file) { |
402 | } |
403 | |
404 | /** |
405 | * @generated |
406 | */ |
407 | public void handleMarkerAdded(IMarker marker) { |
408 | if (marker |
409 | .getAttribute( |
410 | org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID, |
411 | null) != null) { |
412 | handleMarkerChanged(marker); |
413 | } |
414 | } |
415 | |
416 | /** |
417 | * @generated |
418 | */ |
419 | public void handleMarkerDeleted(IMarker marker, Map attributes) { |
420 | String viewId = (String) attributes |
421 | .get(org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID); |
422 | refreshDecorators(viewId, diagram); |
423 | } |
424 | |
425 | /** |
426 | * @generated |
427 | */ |
428 | public void handleMarkerChanged(IMarker marker) { |
429 | if (!MARKER_TYPE.equals(getType(marker))) { |
430 | return; |
431 | } |
432 | String viewId = marker |
433 | .getAttribute( |
434 | org.eclipse.gmf.runtime.common.ui.resources.IMarker.ELEMENT_ID, |
435 | ""); //$NON-NLS-1$ |
436 | refreshDecorators(viewId, diagram); |
437 | } |
438 | |
439 | /** |
440 | * @generated |
441 | */ |
442 | private String getType(IMarker marker) { |
443 | try { |
444 | return marker.getType(); |
445 | } catch (CoreException e) { |
446 | PalladioComponentModelRepositoryDiagramEditorPlugin |
447 | .getInstance().logError( |
448 | "Validation marker refresh failure", e); //$NON-NLS-1$ |
449 | return ""; //$NON-NLS-1$ |
450 | } |
451 | } |
452 | } |
453 | } |