/******************************************************************************* * 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 // } } }