1 | /* |
2 | * Copyright 2007, SDQ, IPD, U KA |
3 | */ |
4 | package de.uka.ipd.sdq.pcm.gmf.allocation.part; |
5 | |
6 | import java.io.IOException; |
7 | import java.util.ArrayList; |
8 | import java.util.Collection; |
9 | import java.util.Collections; |
10 | import java.util.HashMap; |
11 | import java.util.Iterator; |
12 | import java.util.List; |
13 | import java.util.Map; |
14 | |
15 | import org.eclipse.core.commands.ExecutionException; |
16 | import org.eclipse.core.resources.IFile; |
17 | import org.eclipse.core.resources.IResource; |
18 | import org.eclipse.core.resources.IResourceStatus; |
19 | import org.eclipse.core.resources.IStorage; |
20 | import org.eclipse.core.resources.ResourcesPlugin; |
21 | import org.eclipse.core.runtime.CoreException; |
22 | import org.eclipse.core.runtime.IAdaptable; |
23 | import org.eclipse.core.runtime.IProgressMonitor; |
24 | import org.eclipse.core.runtime.IStatus; |
25 | import org.eclipse.core.runtime.Path; |
26 | import org.eclipse.core.runtime.Status; |
27 | import org.eclipse.core.runtime.jobs.ISchedulingRule; |
28 | import org.eclipse.core.runtime.jobs.MultiRule; |
29 | import org.eclipse.emf.common.notify.Adapter; |
30 | import org.eclipse.emf.common.notify.Notification; |
31 | import org.eclipse.emf.common.notify.Notifier; |
32 | import org.eclipse.emf.common.ui.URIEditorInput; |
33 | import org.eclipse.emf.common.util.URI; |
34 | import org.eclipse.emf.ecore.EObject; |
35 | import org.eclipse.emf.ecore.resource.Resource; |
36 | import org.eclipse.emf.ecore.resource.ResourceSet; |
37 | import org.eclipse.emf.ecore.util.EContentAdapter; |
38 | import org.eclipse.emf.ecore.util.EcoreUtil; |
39 | import org.eclipse.emf.ecore.xmi.XMLResource; |
40 | import org.eclipse.emf.transaction.NotificationFilter; |
41 | import org.eclipse.emf.transaction.TransactionalEditingDomain; |
42 | import org.eclipse.emf.workspace.util.WorkspaceSynchronizer; |
43 | import org.eclipse.gmf.runtime.common.core.command.CommandResult; |
44 | import org.eclipse.gmf.runtime.diagram.core.DiagramEditingDomainFactory; |
45 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.AbstractDocumentProvider; |
46 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.DiagramDocument; |
47 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument; |
48 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocumentProvider; |
49 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDocument; |
50 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.EditorStatusCodes; |
51 | import org.eclipse.gmf.runtime.diagram.ui.resources.editor.internal.util.DiagramIOUtil; |
52 | import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; |
53 | import org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory; |
54 | import org.eclipse.gmf.runtime.notation.Diagram; |
55 | import org.eclipse.jface.operation.IRunnableContext; |
56 | import org.eclipse.osgi.util.NLS; |
57 | import org.eclipse.swt.widgets.Display; |
58 | import org.eclipse.ui.IEditorInput; |
59 | import org.eclipse.ui.part.FileEditorInput; |
60 | |
61 | /** |
62 | * @generated |
63 | */ |
64 | public class PalladioComponentModelDocumentProvider extends |
65 | AbstractDocumentProvider implements IDiagramDocumentProvider { |
66 | |
67 | /** |
68 | * @generated |
69 | */ |
70 | protected ElementInfo createElementInfo(Object element) |
71 | throws CoreException { |
72 | if (false == element instanceof FileEditorInput |
73 | && false == element instanceof URIEditorInput) { |
74 | throw new CoreException( |
75 | new Status( |
76 | IStatus.ERROR, |
77 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
78 | 0, |
79 | NLS |
80 | .bind( |
81 | Messages.PalladioComponentModelDocumentProvider_IncorrectInputError, |
82 | new Object[] { |
83 | element, |
84 | "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$ |
85 | null)); |
86 | } |
87 | IEditorInput editorInput = (IEditorInput) element; |
88 | IDiagramDocument document = (IDiagramDocument) createDocument(editorInput); |
89 | |
90 | ResourceSetInfo info = new ResourceSetInfo(document, editorInput); |
91 | info.setModificationStamp(computeModificationStamp(info)); |
92 | info.fStatus = null; |
93 | return info; |
94 | } |
95 | |
96 | /** |
97 | * @generated |
98 | */ |
99 | protected IDocument createDocument(Object element) throws CoreException { |
100 | if (false == element instanceof FileEditorInput |
101 | && false == element instanceof URIEditorInput) { |
102 | throw new CoreException( |
103 | new Status( |
104 | IStatus.ERROR, |
105 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
106 | 0, |
107 | NLS |
108 | .bind( |
109 | Messages.PalladioComponentModelDocumentProvider_IncorrectInputError, |
110 | new Object[] { |
111 | element, |
112 | "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$ |
113 | null)); |
114 | } |
115 | IDocument document = createEmptyDocument(); |
116 | setDocumentContent(document, (IEditorInput) element); |
117 | setupDocument(element, document); |
118 | return document; |
119 | } |
120 | |
121 | /** |
122 | * Sets up the given document as it would be provided for the given element. The |
123 | * content of the document is not changed. This default implementation is empty. |
124 | * Subclasses may reimplement. |
125 | * |
126 | * @param element the blue-print element |
127 | * @param document the document to set up |
128 | * @generated |
129 | */ |
130 | protected void setupDocument(Object element, IDocument document) { |
131 | // for subclasses |
132 | } |
133 | |
134 | /** |
135 | * @generated |
136 | */ |
137 | private long computeModificationStamp(ResourceSetInfo info) { |
138 | int result = 0; |
139 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
140 | .hasNext();) { |
141 | Resource nextResource = (Resource) it.next(); |
142 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
143 | if (file != null) { |
144 | if (file.getLocation() != null) { |
145 | result += file.getLocation().toFile().lastModified(); |
146 | } else { |
147 | result += file.getModificationStamp(); |
148 | } |
149 | } |
150 | } |
151 | return result; |
152 | } |
153 | |
154 | /** |
155 | * @generated |
156 | */ |
157 | protected IDocument createEmptyDocument() { |
158 | DiagramDocument document = new DiagramDocument(); |
159 | document.setEditingDomain(createEditingDomain()); |
160 | return document; |
161 | } |
162 | |
163 | /** |
164 | * @generated |
165 | */ |
166 | private TransactionalEditingDomain createEditingDomain() { |
167 | TransactionalEditingDomain editingDomain = DiagramEditingDomainFactory |
168 | .getInstance().createEditingDomain(); |
169 | editingDomain.setID("de.uka.ipd.sdq.pcm.gmf.allocation.EditingDomain"); //$NON-NLS-1$ |
170 | final NotificationFilter diagramResourceModifiedFilter = NotificationFilter |
171 | .createNotifierFilter(editingDomain.getResourceSet()).and( |
172 | NotificationFilter |
173 | .createEventTypeFilter(Notification.ADD)).and( |
174 | NotificationFilter.createFeatureFilter( |
175 | ResourceSet.class, |
176 | ResourceSet.RESOURCE_SET__RESOURCES)); |
177 | editingDomain.getResourceSet().eAdapters().add(new Adapter() { |
178 | |
179 | private Notifier myTarger; |
180 | |
181 | public Notifier getTarget() { |
182 | return myTarger; |
183 | } |
184 | |
185 | public boolean isAdapterForType(Object type) { |
186 | return false; |
187 | } |
188 | |
189 | public void notifyChanged(Notification notification) { |
190 | if (diagramResourceModifiedFilter.matches(notification)) { |
191 | Object value = notification.getNewValue(); |
192 | if (value instanceof Resource) { |
193 | ((Resource) value).setTrackingModification(true); |
194 | } |
195 | } |
196 | } |
197 | |
198 | public void setTarget(Notifier newTarget) { |
199 | myTarger = newTarget; |
200 | } |
201 | |
202 | }); |
203 | |
204 | return editingDomain; |
205 | } |
206 | |
207 | /** |
208 | * @generated |
209 | */ |
210 | protected void setDocumentContent(IDocument document, IEditorInput element) |
211 | throws CoreException { |
212 | IDiagramDocument diagramDocument = (IDiagramDocument) document; |
213 | TransactionalEditingDomain domain = diagramDocument.getEditingDomain(); |
214 | if (element instanceof FileEditorInput) { |
215 | IStorage storage = ((FileEditorInput) element).getStorage(); |
216 | Diagram diagram = DiagramIOUtil.load(domain, storage, true, |
217 | getProgressMonitor()); |
218 | document.setContent(diagram); |
219 | } else if (element instanceof URIEditorInput) { |
220 | URI uri = ((URIEditorInput) element).getURI(); |
221 | Resource resource = null; |
222 | try { |
223 | resource = domain.getResourceSet().getResource( |
224 | uri.trimFragment(), false); |
225 | if (resource == null) { |
226 | resource = domain.getResourceSet().createResource( |
227 | uri.trimFragment()); |
228 | } |
229 | if (!resource.isLoaded()) { |
230 | try { |
231 | Map options = new HashMap(GMFResourceFactory |
232 | .getDefaultLoadOptions()); |
233 | // @see 171060 |
234 | // options.put(org.eclipse.emf.ecore.xmi.XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE); |
235 | resource.load(options); |
236 | } catch (IOException e) { |
237 | resource.unload(); |
238 | throw e; |
239 | } |
240 | } |
241 | if (uri.fragment() != null) { |
242 | EObject rootElement = resource.getEObject(uri.fragment()); |
243 | if (rootElement instanceof Diagram) { |
244 | document.setContent((Diagram) rootElement); |
245 | return; |
246 | } |
247 | } else { |
248 | for (Iterator it = resource.getContents().iterator(); it |
249 | .hasNext();) { |
250 | Object rootElement = it.next(); |
251 | if (rootElement instanceof Diagram) { |
252 | document.setContent((Diagram) rootElement); |
253 | return; |
254 | } |
255 | } |
256 | } |
257 | throw new RuntimeException( |
258 | Messages.PalladioComponentModelDocumentProvider_NoDiagramInResourceError); |
259 | } catch (Exception e) { |
260 | CoreException thrownExcp = null; |
261 | if (e instanceof CoreException) { |
262 | thrownExcp = (CoreException) e; |
263 | } else { |
264 | String msg = e.getLocalizedMessage(); |
265 | thrownExcp = new CoreException( |
266 | new Status( |
267 | IStatus.ERROR, |
268 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
269 | 0, |
270 | msg != null ? msg |
271 | : Messages.PalladioComponentModelDocumentProvider_DiagramLoadingError, |
272 | e)); |
273 | } |
274 | throw thrownExcp; |
275 | } |
276 | } else { |
277 | throw new CoreException( |
278 | new Status( |
279 | IStatus.ERROR, |
280 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
281 | 0, |
282 | NLS |
283 | .bind( |
284 | Messages.PalladioComponentModelDocumentProvider_IncorrectInputError, |
285 | new Object[] { |
286 | element, |
287 | "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$ |
288 | null)); |
289 | } |
290 | } |
291 | |
292 | /** |
293 | * @generated |
294 | */ |
295 | public long getModificationStamp(Object element) { |
296 | ResourceSetInfo info = getResourceSetInfo(element); |
297 | if (info != null) { |
298 | return computeModificationStamp(info); |
299 | } |
300 | return super.getModificationStamp(element); |
301 | } |
302 | |
303 | /** |
304 | * @generated |
305 | */ |
306 | public boolean isDeleted(Object element) { |
307 | IDiagramDocument document = getDiagramDocument(element); |
308 | if (document != null) { |
309 | Resource diagramResource = document.getDiagram().eResource(); |
310 | if (diagramResource != null) { |
311 | IFile file = WorkspaceSynchronizer.getFile(diagramResource); |
312 | return file == null || file.getLocation() == null |
313 | || !file.getLocation().toFile().exists(); |
314 | } |
315 | } |
316 | return super.isDeleted(element); |
317 | } |
318 | |
319 | /** |
320 | * @generated |
321 | */ |
322 | public ResourceSetInfo getResourceSetInfo(Object editorInput) { |
323 | return (ResourceSetInfo) super.getElementInfo(editorInput); |
324 | } |
325 | |
326 | /** |
327 | * @generated |
328 | */ |
329 | protected void disposeElementInfo(Object element, ElementInfo info) { |
330 | if (info instanceof ResourceSetInfo) { |
331 | ResourceSetInfo resourceSetInfo = (ResourceSetInfo) info; |
332 | resourceSetInfo.dispose(); |
333 | } |
334 | super.disposeElementInfo(element, info); |
335 | } |
336 | |
337 | /** |
338 | * @generated |
339 | */ |
340 | protected void doValidateState(Object element, Object computationContext) |
341 | throws CoreException { |
342 | ResourceSetInfo info = getResourceSetInfo(element); |
343 | if (info != null) { |
344 | Collection files2Validate = new ArrayList(); |
345 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
346 | .hasNext();) { |
347 | Resource nextResource = (Resource) it.next(); |
348 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
349 | if (file != null && file.isReadOnly()) { |
350 | files2Validate.add(file); |
351 | } |
352 | } |
353 | ResourcesPlugin.getWorkspace().validateEdit( |
354 | (IFile[]) files2Validate.toArray(new IFile[files2Validate |
355 | .size()]), computationContext); |
356 | } |
357 | |
358 | super.doValidateState(element, computationContext); |
359 | } |
360 | |
361 | /** |
362 | * @generated |
363 | */ |
364 | public boolean isReadOnly(Object element) { |
365 | ResourceSetInfo info = getResourceSetInfo(element); |
366 | if (info != null) { |
367 | if (info.isUpdateCache()) { |
368 | try { |
369 | updateCache(element); |
370 | } catch (CoreException ex) { |
371 | PalladioComponentModelAllocationDiagramEditorPlugin |
372 | .getInstance() |
373 | .logError( |
374 | Messages.PalladioComponentModelDocumentProvider_isModifiable, |
375 | ex); |
376 | // Error message to log was initially taken from org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.internal.l10n.EditorMessages.StorageDocumentProvider_isModifiable |
377 | } |
378 | } |
379 | return info.isReadOnly(); |
380 | } |
381 | return super.isReadOnly(element); |
382 | } |
383 | |
384 | /** |
385 | * @generated |
386 | */ |
387 | public boolean isModifiable(Object element) { |
388 | if (!isStateValidated(element)) { |
389 | if (element instanceof FileEditorInput |
390 | || element instanceof URIEditorInput) { |
391 | return true; |
392 | } |
393 | } |
394 | ResourceSetInfo info = getResourceSetInfo(element); |
395 | if (info != null) { |
396 | if (info.isUpdateCache()) { |
397 | try { |
398 | updateCache(element); |
399 | } catch (CoreException ex) { |
400 | PalladioComponentModelAllocationDiagramEditorPlugin |
401 | .getInstance() |
402 | .logError( |
403 | Messages.PalladioComponentModelDocumentProvider_isModifiable, |
404 | ex); |
405 | // Error message to log was initially taken from org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.internal.l10n.EditorMessages.StorageDocumentProvider_isModifiable |
406 | } |
407 | } |
408 | return info.isModifiable(); |
409 | } |
410 | return super.isModifiable(element); |
411 | } |
412 | |
413 | /** |
414 | * @generated |
415 | */ |
416 | protected void updateCache(Object element) throws CoreException { |
417 | ResourceSetInfo info = getResourceSetInfo(element); |
418 | if (info != null) { |
419 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
420 | .hasNext();) { |
421 | Resource nextResource = (Resource) it.next(); |
422 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
423 | if (file != null && file.isReadOnly()) { |
424 | info.setReadOnly(true); |
425 | info.setModifiable(false); |
426 | return; |
427 | } |
428 | } |
429 | info.setReadOnly(false); |
430 | info.setModifiable(true); |
431 | return; |
432 | } |
433 | } |
434 | |
435 | /** |
436 | * @generated |
437 | */ |
438 | protected void doUpdateStateCache(Object element) throws CoreException { |
439 | ResourceSetInfo info = getResourceSetInfo(element); |
440 | if (info != null) { |
441 | info.setUpdateCache(true); |
442 | } |
443 | super.doUpdateStateCache(element); |
444 | } |
445 | |
446 | /** |
447 | * @generated |
448 | */ |
449 | public boolean isSynchronized(Object element) { |
450 | ResourceSetInfo info = getResourceSetInfo(element); |
451 | if (info != null) { |
452 | return info.isSynchronized(); |
453 | } |
454 | return super.isSynchronized(element); |
455 | } |
456 | |
457 | /** |
458 | * @generated |
459 | */ |
460 | protected ISchedulingRule getResetRule(Object element) { |
461 | ResourceSetInfo info = getResourceSetInfo(element); |
462 | if (info != null) { |
463 | Collection rules = new ArrayList(); |
464 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
465 | .hasNext();) { |
466 | Resource nextResource = (Resource) it.next(); |
467 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
468 | if (file != null) { |
469 | rules.add(ResourcesPlugin.getWorkspace().getRuleFactory() |
470 | .modifyRule(file)); |
471 | } |
472 | } |
473 | return new MultiRule((ISchedulingRule[]) rules |
474 | .toArray(new ISchedulingRule[rules.size()])); |
475 | } |
476 | return null; |
477 | } |
478 | |
479 | /** |
480 | * @generated |
481 | */ |
482 | protected ISchedulingRule getSaveRule(Object element) { |
483 | ResourceSetInfo info = getResourceSetInfo(element); |
484 | if (info != null) { |
485 | Collection rules = new ArrayList(); |
486 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
487 | .hasNext();) { |
488 | Resource nextResource = (Resource) it.next(); |
489 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
490 | if (file != null) { |
491 | rules.add(computeSchedulingRule(file)); |
492 | } |
493 | } |
494 | return new MultiRule((ISchedulingRule[]) rules |
495 | .toArray(new ISchedulingRule[rules.size()])); |
496 | } |
497 | return null; |
498 | } |
499 | |
500 | /** |
501 | * @generated |
502 | */ |
503 | protected ISchedulingRule getSynchronizeRule(Object element) { |
504 | ResourceSetInfo info = getResourceSetInfo(element); |
505 | if (info != null) { |
506 | Collection rules = new ArrayList(); |
507 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
508 | .hasNext();) { |
509 | Resource nextResource = (Resource) it.next(); |
510 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
511 | if (file != null) { |
512 | rules.add(ResourcesPlugin.getWorkspace().getRuleFactory() |
513 | .refreshRule(file)); |
514 | } |
515 | } |
516 | return new MultiRule((ISchedulingRule[]) rules |
517 | .toArray(new ISchedulingRule[rules.size()])); |
518 | } |
519 | return null; |
520 | } |
521 | |
522 | /** |
523 | * @generated |
524 | */ |
525 | protected ISchedulingRule getValidateStateRule(Object element) { |
526 | ResourceSetInfo info = getResourceSetInfo(element); |
527 | if (info != null) { |
528 | Collection files = new ArrayList(); |
529 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
530 | .hasNext();) { |
531 | Resource nextResource = (Resource) it.next(); |
532 | IFile file = WorkspaceSynchronizer.getFile(nextResource); |
533 | if (file != null) { |
534 | files.add(file); |
535 | } |
536 | } |
537 | return ResourcesPlugin.getWorkspace().getRuleFactory() |
538 | .validateEditRule( |
539 | (IFile[]) files.toArray(new IFile[files.size()])); |
540 | } |
541 | return null; |
542 | } |
543 | |
544 | /** |
545 | * @generated |
546 | */ |
547 | private ISchedulingRule computeSchedulingRule(IResource toCreateOrModify) { |
548 | if (toCreateOrModify.exists()) |
549 | return ResourcesPlugin.getWorkspace().getRuleFactory().modifyRule( |
550 | toCreateOrModify); |
551 | |
552 | IResource parent = toCreateOrModify; |
553 | do { |
554 | /* |
555 | * XXX This is a workaround for |
556 | * https://bugs.eclipse.org/bugs/show_bug.cgi?id=67601 |
557 | * IResourceRuleFactory.createRule should iterate the hierarchy |
558 | * itself. |
559 | */ |
560 | toCreateOrModify = parent; |
561 | parent = toCreateOrModify.getParent(); |
562 | } while (parent != null && !parent.exists()); |
563 | |
564 | return ResourcesPlugin.getWorkspace().getRuleFactory().createRule( |
565 | toCreateOrModify); |
566 | } |
567 | |
568 | /** |
569 | * @generated |
570 | */ |
571 | protected void doSynchronize(Object element, IProgressMonitor monitor) |
572 | throws CoreException { |
573 | ResourceSetInfo info = getResourceSetInfo(element); |
574 | if (info != null) { |
575 | for (Iterator it = info.getResourceSet().getResources().iterator(); it |
576 | .hasNext();) { |
577 | Resource nextResource = (Resource) it.next(); |
578 | handleElementChanged(info, nextResource, monitor); |
579 | } |
580 | return; |
581 | } |
582 | super.doSynchronize(element, monitor); |
583 | } |
584 | |
585 | /** |
586 | * @generated |
587 | */ |
588 | protected void doSaveDocument(IProgressMonitor monitor, Object element, |
589 | IDocument document, boolean overwrite) throws CoreException { |
590 | ResourceSetInfo info = getResourceSetInfo(element); |
591 | if (info != null) { |
592 | if (!overwrite && !info.isSynchronized()) { |
593 | throw new CoreException( |
594 | new Status( |
595 | IStatus.ERROR, |
596 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
597 | IResourceStatus.OUT_OF_SYNC_LOCAL, |
598 | Messages.PalladioComponentModelDocumentProvider_UnsynchronizedFileSaveError, |
599 | null)); |
600 | } |
601 | info.stopResourceListening(); |
602 | fireElementStateChanging(element); |
603 | List resources = info.getResourceSet().getResources(); |
604 | try { |
605 | monitor |
606 | .beginTask( |
607 | Messages.PalladioComponentModelDocumentProvider_SaveDiagramTask, |
608 | resources.size() + 1); //"Saving diagram" |
609 | for (Iterator it = resources.iterator(); it.hasNext();) { |
610 | Resource nextResource = (Resource) it.next(); |
611 | monitor |
612 | .setTaskName(NLS |
613 | .bind( |
614 | Messages.PalladioComponentModelDocumentProvider_SaveNextResourceTask, |
615 | nextResource.getURI())); |
616 | if (nextResource.isLoaded() |
617 | && !info.getEditingDomain() |
618 | .isReadOnly(nextResource)) { |
619 | try { |
620 | nextResource |
621 | .save(PalladioComponentModelDiagramEditorUtil |
622 | .getSaveOptions()); |
623 | } catch (IOException e) { |
624 | fireElementStateChangeFailed(element); |
625 | throw new CoreException( |
626 | new Status( |
627 | IStatus.ERROR, |
628 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
629 | EditorStatusCodes.RESOURCE_FAILURE, |
630 | e.getLocalizedMessage(), null)); |
631 | } |
632 | } |
633 | monitor.worked(1); |
634 | } |
635 | monitor.done(); |
636 | info.setModificationStamp(computeModificationStamp(info)); |
637 | } catch (RuntimeException x) { |
638 | fireElementStateChangeFailed(element); |
639 | throw x; |
640 | } finally { |
641 | info.startResourceListening(); |
642 | } |
643 | } else { |
644 | URI newResoruceURI; |
645 | List affectedFiles = null; |
646 | if (element instanceof FileEditorInput) { |
647 | IFile newFile = ((FileEditorInput) element).getFile(); |
648 | affectedFiles = Collections.singletonList(newFile); |
649 | newResoruceURI = URI.createPlatformResourceURI(newFile |
650 | .getFullPath().toString(), true); |
651 | } else if (element instanceof URIEditorInput) { |
652 | newResoruceURI = ((URIEditorInput) element).getURI(); |
653 | } else { |
654 | fireElementStateChangeFailed(element); |
655 | throw new CoreException( |
656 | new Status( |
657 | IStatus.ERROR, |
658 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
659 | 0, |
660 | NLS |
661 | .bind( |
662 | Messages.PalladioComponentModelDocumentProvider_IncorrectInputError, |
663 | new Object[] { |
664 | element, |
665 | "org.eclipse.ui.part.FileEditorInput", "org.eclipse.emf.common.ui.URIEditorInput" }), //$NON-NLS-1$ //$NON-NLS-2$ |
666 | null)); |
667 | } |
668 | if (false == document instanceof IDiagramDocument) { |
669 | fireElementStateChangeFailed(element); |
670 | throw new CoreException( |
671 | new Status( |
672 | IStatus.ERROR, |
673 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
674 | 0, |
675 | "Incorrect document used: " + document + " instead of org.eclipse.gmf.runtime.diagram.ui.resources.editor.document.IDiagramDocument", null)); //$NON-NLS-1$ //$NON-NLS-2$ |
676 | } |
677 | IDiagramDocument diagramDocument = (IDiagramDocument) document; |
678 | final Resource newResource = diagramDocument.getEditingDomain() |
679 | .getResourceSet().createResource(newResoruceURI); |
680 | final Diagram diagramCopy = (Diagram) EcoreUtil |
681 | .copy(diagramDocument.getDiagram()); |
682 | try { |
683 | new AbstractTransactionalCommand( |
684 | diagramDocument.getEditingDomain(), |
685 | NLS |
686 | .bind( |
687 | Messages.PalladioComponentModelDocumentProvider_SaveAsOperation, |
688 | diagramCopy.getName()), affectedFiles) { |
689 | protected CommandResult doExecuteWithResult( |
690 | IProgressMonitor monitor, IAdaptable info) |
691 | throws ExecutionException { |
692 | newResource.getContents().add(diagramCopy); |
693 | return CommandResult.newOKCommandResult(); |
694 | } |
695 | }.execute(monitor, null); |
696 | newResource.save(PalladioComponentModelDiagramEditorUtil |
697 | .getSaveOptions()); |
698 | } catch (ExecutionException e) { |
699 | fireElementStateChangeFailed(element); |
700 | throw new CoreException(new Status(IStatus.ERROR, |
701 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
702 | 0, e.getLocalizedMessage(), null)); |
703 | } catch (IOException e) { |
704 | fireElementStateChangeFailed(element); |
705 | throw new CoreException(new Status(IStatus.ERROR, |
706 | PalladioComponentModelAllocationDiagramEditorPlugin.ID, |
707 | 0, e.getLocalizedMessage(), null)); |
708 | } |
709 | newResource.unload(); |
710 | } |
711 | } |
712 | |
713 | /** |
714 | * @generated |
715 | */ |
716 | protected void handleElementChanged(ResourceSetInfo info, |
717 | Resource changedResource, IProgressMonitor monitor) { |
718 | IFile file = WorkspaceSynchronizer.getFile(changedResource); |
719 | if (file != null) { |
720 | try { |
721 | file.refreshLocal(IResource.DEPTH_INFINITE, monitor); |
722 | } catch (CoreException ex) { |
723 | PalladioComponentModelAllocationDiagramEditorPlugin |
724 | .getInstance() |
725 | .logError( |
726 | Messages.PalladioComponentModelDocumentProvider_handleElementContentChanged, |
727 | ex); |
728 | // Error message to log was initially taken from org.eclipse.gmf.runtime.diagram.ui.resources.editor.ide.internal.l10n.EditorMessages.FileDocumentProvider_handleElementContentChanged |
729 | } |
730 | } |
731 | changedResource.unload(); |
732 | |
733 | fireElementContentAboutToBeReplaced(info.getEditorInput()); |
734 | removeUnchangedElementListeners(info.getEditorInput(), info); |
735 | info.fStatus = null; |
736 | try { |
737 | setDocumentContent(info.fDocument, info.getEditorInput()); |
738 | } catch (CoreException e) { |
739 | info.fStatus = e.getStatus(); |
740 | } |
741 | if (!info.fCanBeSaved) { |
742 | info.setModificationStamp(computeModificationStamp(info)); |
743 | } |
744 | addUnchangedElementListeners(info.getEditorInput(), info); |
745 | fireElementContentReplaced(info.getEditorInput()); |
746 | } |
747 | |
748 | /** |
749 | * @generated |
750 | */ |
751 | protected void handleElementMoved(IEditorInput input, URI uri) { |
752 | if (input instanceof FileEditorInput) { |
753 | IFile newFile = ResourcesPlugin.getWorkspace().getRoot().getFile( |
754 | new Path(URI.decode(uri.path())).removeFirstSegments(1)); |
755 | fireElementMoved(input, newFile == null ? null |
756 | : new FileEditorInput(newFile)); |
757 | return; |
758 | } |
759 | // TODO: append suffix to the URI! (use diagram as a parameter) |
760 | fireElementMoved(input, new URIEditorInput(uri)); |
761 | } |
762 | |
763 | /** |
764 | * @generated |
765 | */ |
766 | public IEditorInput createInputWithEditingDomain(IEditorInput editorInput, |
767 | TransactionalEditingDomain domain) { |
768 | return editorInput; |
769 | } |
770 | |
771 | /** |
772 | * @generated |
773 | */ |
774 | public IDiagramDocument getDiagramDocument(Object element) { |
775 | IDocument doc = getDocument(element); |
776 | if (doc instanceof IDiagramDocument) { |
777 | return (IDiagramDocument) doc; |
778 | } |
779 | return null; |
780 | } |
781 | |
782 | /** |
783 | * @generated |
784 | */ |
785 | protected IRunnableContext getOperationRunner(IProgressMonitor monitor) { |
786 | return null; |
787 | } |
788 | |
789 | /** |
790 | * @generated |
791 | */ |
792 | protected class ResourceSetInfo extends ElementInfo { |
793 | |
794 | /** |
795 | * @generated |
796 | */ |
797 | private long myModificationStamp = IResource.NULL_STAMP; |
798 | |
799 | /** |
800 | * @generated |
801 | */ |
802 | private WorkspaceSynchronizer mySynchronizer; |
803 | |
804 | /** |
805 | * @generated |
806 | */ |
807 | private Collection myUnSynchronizedResources = new ArrayList(); |
808 | |
809 | /** |
810 | * @generated |
811 | */ |
812 | private IDiagramDocument myDocument; |
813 | |
814 | /** |
815 | * @generated |
816 | */ |
817 | private IEditorInput myEditorInput; |
818 | |
819 | /** |
820 | * @generated |
821 | */ |
822 | private boolean myUpdateCache = true; |
823 | |
824 | /** |
825 | * @generated |
826 | */ |
827 | private boolean myModifiable = false; |
828 | |
829 | /** |
830 | * @generated |
831 | */ |
832 | private boolean myReadOnly = true; |
833 | |
834 | /** |
835 | * @generated |
836 | */ |
837 | private ResourceSetModificationListener myResourceSetListener; |
838 | |
839 | /** |
840 | * @generated |
841 | */ |
842 | public ResourceSetInfo(IDiagramDocument document, |
843 | IEditorInput editorInput) { |
844 | super(document); |
845 | myDocument = document; |
846 | myEditorInput = editorInput; |
847 | startResourceListening(); |
848 | myResourceSetListener = new ResourceSetModificationListener(this); |
849 | getResourceSet().eAdapters().add(myResourceSetListener); |
850 | } |
851 | |
852 | /** |
853 | * @generated |
854 | */ |
855 | public long getModificationStamp() { |
856 | return myModificationStamp; |
857 | } |
858 | |
859 | /** |
860 | * @generated |
861 | */ |
862 | public void setModificationStamp(long modificationStamp) { |
863 | myModificationStamp = modificationStamp; |
864 | } |
865 | |
866 | /** |
867 | * @generated |
868 | */ |
869 | public TransactionalEditingDomain getEditingDomain() { |
870 | return myDocument.getEditingDomain(); |
871 | } |
872 | |
873 | /** |
874 | * @generated |
875 | */ |
876 | public ResourceSet getResourceSet() { |
877 | return getEditingDomain().getResourceSet(); |
878 | } |
879 | |
880 | /** |
881 | * @generated |
882 | */ |
883 | public IEditorInput getEditorInput() { |
884 | return myEditorInput; |
885 | } |
886 | |
887 | /** |
888 | * @generated |
889 | */ |
890 | public void dispose() { |
891 | stopResourceListening(); |
892 | getResourceSet().eAdapters().remove(myResourceSetListener); |
893 | for (Iterator it = getResourceSet().getResources().iterator(); it |
894 | .hasNext();) { |
895 | Resource resource = (Resource) it.next(); |
896 | resource.unload(); |
897 | } |
898 | } |
899 | |
900 | /** |
901 | * @generated |
902 | */ |
903 | public boolean isSynchronized() { |
904 | return myUnSynchronizedResources.size() == 0; |
905 | } |
906 | |
907 | /** |
908 | * @generated |
909 | */ |
910 | public void setUnSynchronized(Resource resource) { |
911 | myUnSynchronizedResources.add(resource); |
912 | } |
913 | |
914 | /** |
915 | * @generated |
916 | */ |
917 | public void setSynchronized(Resource resource) { |
918 | myUnSynchronizedResources.remove(resource); |
919 | } |
920 | |
921 | /** |
922 | * @generated |
923 | */ |
924 | public final void stopResourceListening() { |
925 | mySynchronizer.dispose(); |
926 | mySynchronizer = null; |
927 | } |
928 | |
929 | /** |
930 | * @generated |
931 | */ |
932 | public final void startResourceListening() { |
933 | mySynchronizer = new WorkspaceSynchronizer(getEditingDomain(), |
934 | new SynchronizerDelegate()); |
935 | } |
936 | |
937 | /** |
938 | * @generated |
939 | */ |
940 | public boolean isUpdateCache() { |
941 | return myUpdateCache; |
942 | } |
943 | |
944 | /** |
945 | * @generated |
946 | */ |
947 | public void setUpdateCache(boolean update) { |
948 | myUpdateCache = update; |
949 | } |
950 | |
951 | /** |
952 | * @generated |
953 | */ |
954 | public boolean isModifiable() { |
955 | return myModifiable; |
956 | } |
957 | |
958 | /** |
959 | * @generated |
960 | */ |
961 | public void setModifiable(boolean modifiable) { |
962 | myModifiable = modifiable; |
963 | } |
964 | |
965 | /** |
966 | * @generated |
967 | */ |
968 | public boolean isReadOnly() { |
969 | return myReadOnly; |
970 | } |
971 | |
972 | /** |
973 | * @generated |
974 | */ |
975 | public void setReadOnly(boolean readOnly) { |
976 | myReadOnly = readOnly; |
977 | } |
978 | |
979 | /** |
980 | * @generated |
981 | */ |
982 | private class SynchronizerDelegate implements |
983 | WorkspaceSynchronizer.Delegate { |
984 | |
985 | /** |
986 | * @generated |
987 | */ |
988 | public void dispose() { |
989 | } |
990 | |
991 | /** |
992 | * @generated |
993 | */ |
994 | public boolean handleResourceChanged(final Resource resource) { |
995 | synchronized (ResourceSetInfo.this) { |
996 | if (ResourceSetInfo.this.fCanBeSaved) { |
997 | ResourceSetInfo.this.setUnSynchronized(resource); |
998 | return true; |
999 | } |
1000 | } |
1001 | Display.getDefault().asyncExec(new Runnable() { |
1002 | public void run() { |
1003 | handleElementChanged(ResourceSetInfo.this, resource, |
1004 | null); |
1005 | } |
1006 | }); |
1007 | return true; |
1008 | } |
1009 | |
1010 | /** |
1011 | * @generated |
1012 | */ |
1013 | public boolean handleResourceDeleted(Resource resource) { |
1014 | synchronized (ResourceSetInfo.this) { |
1015 | if (ResourceSetInfo.this.fCanBeSaved) { |
1016 | ResourceSetInfo.this.setUnSynchronized(resource); |
1017 | return true; |
1018 | } |
1019 | } |
1020 | Display.getDefault().asyncExec(new Runnable() { |
1021 | public void run() { |
1022 | fireElementDeleted(ResourceSetInfo.this |
1023 | .getEditorInput()); |
1024 | } |
1025 | }); |
1026 | return true; |
1027 | } |
1028 | |
1029 | /** |
1030 | * @generated |
1031 | */ |
1032 | public boolean handleResourceMoved(Resource resource, |
1033 | final URI newURI) { |
1034 | synchronized (ResourceSetInfo.this) { |
1035 | if (ResourceSetInfo.this.fCanBeSaved) { |
1036 | ResourceSetInfo.this.setUnSynchronized(resource); |
1037 | return true; |
1038 | } |
1039 | } |
1040 | if (myDocument.getDiagram().eResource() == resource) { |
1041 | Display.getDefault().asyncExec(new Runnable() { |
1042 | public void run() { |
1043 | handleElementMoved(ResourceSetInfo.this |
1044 | .getEditorInput(), newURI); |
1045 | } |
1046 | }); |
1047 | } else { |
1048 | handleResourceDeleted(resource); |
1049 | } |
1050 | return true; |
1051 | } |
1052 | |
1053 | } |
1054 | |
1055 | } |
1056 | |
1057 | /** |
1058 | * @generated |
1059 | */ |
1060 | private class ResourceSetModificationListener extends EContentAdapter { |
1061 | |
1062 | /** |
1063 | * @generated |
1064 | */ |
1065 | private NotificationFilter myModifiedFilter; |
1066 | |
1067 | /** |
1068 | * @generated |
1069 | */ |
1070 | private ResourceSetInfo myInfo; |
1071 | |
1072 | /** |
1073 | * @generated |
1074 | */ |
1075 | public ResourceSetModificationListener(ResourceSetInfo info) { |
1076 | myInfo = info; |
1077 | myModifiedFilter = NotificationFilter.createEventTypeFilter( |
1078 | Notification.SET).or( |
1079 | NotificationFilter |
1080 | .createEventTypeFilter(Notification.UNSET)).and( |
1081 | NotificationFilter.createFeatureFilter(Resource.class, |
1082 | Resource.RESOURCE__IS_MODIFIED)); |
1083 | } |
1084 | |
1085 | /** |
1086 | * @generated |
1087 | */ |
1088 | public void notifyChanged(Notification notification) { |
1089 | if (notification.getNotifier() instanceof ResourceSet) { |
1090 | super.notifyChanged(notification); |
1091 | } |
1092 | if (!notification.isTouch() |
1093 | && myModifiedFilter.matches(notification)) { |
1094 | if (notification.getNotifier() instanceof Resource) { |
1095 | Resource resource = (Resource) notification.getNotifier(); |
1096 | if (resource.isLoaded()) { |
1097 | boolean modified = false; |
1098 | for (Iterator it = myInfo.getResourceSet() |
1099 | .getResources().iterator(); it.hasNext() |
1100 | && !modified;) { |
1101 | Resource nextResource = (Resource) it.next(); |
1102 | if (nextResource.isLoaded()) { |
1103 | modified = nextResource.isModified(); |
1104 | } |
1105 | } |
1106 | boolean dirtyStateChanged = false; |
1107 | synchronized (myInfo) { |
1108 | if (modified != myInfo.fCanBeSaved) { |
1109 | myInfo.fCanBeSaved = modified; |
1110 | dirtyStateChanged = true; |
1111 | } |
1112 | if (!resource.isModified()) { |
1113 | myInfo.setSynchronized(resource); |
1114 | } |
1115 | } |
1116 | if (dirtyStateChanged) { |
1117 | fireElementDirtyStateChanged(myInfo |
1118 | .getEditorInput(), modified); |
1119 | |
1120 | if (!modified) { |
1121 | myInfo |
1122 | .setModificationStamp(computeModificationStamp(myInfo)); |
1123 | } |
1124 | } |
1125 | } |
1126 | } |
1127 | } |
1128 | } |
1129 | |
1130 | } |
1131 | |
1132 | } |