Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: da843575b0067f59bd1a071242f0a2e6252dbb68 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*******************************************************************************
 * Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.xtext.gmf.glue.editingdomain;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IOperationHistoryListener;
import org.eclipse.core.commands.operations.OperationHistoryEvent;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.TransactionalEditingDomainEvent;
import org.eclipse.emf.transaction.TransactionalEditingDomainListener;
import org.eclipse.emf.transaction.TransactionalEditingDomain.Lifecycle;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.emf.workspace.IWorkspaceCommandStack;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.xtext.gmf.glue.Activator;
//import org.eclipse.xtext.parsetree.CompositeNode;
//import org.eclipse.xtext.parsetree.NodeAdapter;
//import org.eclipse.xtext.parsetree.NodeUtil;
import org.eclipse.xtext.parsetree.reconstr.Serializer;
import org.eclipse.xtext.resource.XtextResource;

/**
 * Reconciles the node models of all XtextResources in a TransactionalEditingDomain with semantic changes.
 * 
 * @author koehnlein
 */
public class XtextNodeModelReconciler extends AdapterImpl implements TransactionalEditingDomainListener,
		IOperationHistoryListener {

	private TransactionalEditingDomain editingDomain;

	private ChangeAggregatorAdapter changeAggregator;

	private XtextNodeModelReconciler(TransactionalEditingDomain editingDomain) {
		this.editingDomain = editingDomain;
		Lifecycle lifecycle = TransactionUtil.getAdapter(editingDomain, Lifecycle.class);
		lifecycle.addTransactionalEditingDomainListener(this);
		changeAggregator = new ChangeAggregatorAdapter();
		editingDomain.getResourceSet().eAdapters().add(changeAggregator);
		CommandStack commandStack = editingDomain.getCommandStack();
		if (commandStack instanceof IWorkspaceCommandStack) {
			IOperationHistory operationHistory = ((IWorkspaceCommandStack) commandStack).getOperationHistory();
			operationHistory.addOperationHistoryListener(this);
		}
		changeAggregator.beginRecording();
	}

	public void editingDomainDisposing(TransactionalEditingDomainEvent event) {
		changeAggregator.endRecording();
		CommandStack commandStack = editingDomain.getCommandStack();
		if (commandStack instanceof IWorkspaceCommandStack) {
			IOperationHistory operationHistory = ((IWorkspaceCommandStack) commandStack).getOperationHistory();
			operationHistory.removeOperationHistoryListener(this);
		}
		editingDomain.getResourceSet().eAdapters().remove(changeAggregator);
		Lifecycle lifecycle = TransactionUtil.getAdapter(editingDomain, Lifecycle.class);
		lifecycle.removeTransactionalEditingDomainListener(XtextNodeModelReconciler.this);
	}

	public void transactionClosed(TransactionalEditingDomainEvent event) {
		// ignore
	}

	public void transactionClosing(TransactionalEditingDomainEvent event) {
		// ignore
	}

	public void transactionInterrupted(TransactionalEditingDomainEvent event) {
		// ignore
	}

	public void transactionStarted(TransactionalEditingDomainEvent event) {
		// ignore
	}

	public void transactionStarting(TransactionalEditingDomainEvent event) {
		// ignore
	}

	/**
	 * This element comes from the XText/GMF integration example, and was not originally documented.
	 * @param editingDomain 
	 * @return XtextNodeModelReconciler
	 *
	 */
	public static XtextNodeModelReconciler adapt(TransactionalEditingDomain editingDomain) {
		XtextNodeModelReconciler adapter = (XtextNodeModelReconciler) EcoreUtil.getAdapter(editingDomain
				.getResourceSet().eAdapters(), XtextNodeModelReconciler.class);
		if (adapter == null) {
			adapter = new XtextNodeModelReconciler(editingDomain);
		}
		return adapter;
	}

	public void historyNotification(OperationHistoryEvent event) {
		int eventType = event.getEventType();
//		switch (eventType) {
//			case OperationHistoryEvent.DONE:
//			case OperationHistoryEvent.UNDONE:
//			case OperationHistoryEvent.REDONE:
//				changeAggregator.endRecording();
//				ICommand updateXtextResourceTextCommand = null;
//				for (EObject modificationRoot : changeAggregator.getModificationRoots()) {
//					XtextResource xtextResource = (XtextResource) modificationRoot.eResource();
//					NodeAdapter nodeAdapter = NodeUtil.getNodeAdapter(modificationRoot);
//					CompositeNode parserNode = nodeAdapter.getParserNode();
//					Serializer serializer = xtextResource.getSerializer();
//					String newText = serializer.serialize(modificationRoot);
//					ICommand newCommand = UpdateXtextResourceTextCommand.createUpdateCommand(xtextResource, parserNode
//							.getOffset(), parserNode.getLength(), newText);
//					if (updateXtextResourceTextCommand == null) {
//						updateXtextResourceTextCommand = newCommand;
//					} else {
//						updateXtextResourceTextCommand.compose(newCommand);
//					}
//				}
//				try {
//					if (updateXtextResourceTextCommand != null) {
//						updateXtextResourceTextCommand.execute(null, null);
//					}
//				} catch (ExecutionException exc) {
//					Activator.logError(exc);
//				}
//				changeAggregator.beginRecording();
//				break;
//			default:
//				// ignore
//		}

	}
}

Back to the top