/******************************************************************************* * Copyright (c) 2010 SAP AG. * 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 * * Contributors: * Emil Simeonov - initial API and implementation. * Dimitar Donchev - initial API and implementation. * Dimitar Tenev - initial API and implementation. * Nevena Manova - initial API and implementation. * Georgi Konstantinov - initial API and implementation. *******************************************************************************/ package org.eclipse.wst.sse.sieditor.command.common; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.transaction.Transaction; import org.eclipse.emf.transaction.impl.TransactionImpl; import org.eclipse.emf.workspace.AbstractEMFOperation; import org.eclipse.wst.sse.sieditor.model.api.IModelObject; import org.eclipse.wst.sse.sieditor.model.api.IModelRoot; /** * Abstract command to be implemented for ensuring that the notificaiton's are * delivered if the command is successful. */ public abstract class AbstractNotificationOperation extends AbstractEMFOperation { private final IModelObject[] modelObjects; protected IModelObject modelObject; protected final IModelRoot root; protected final String operationLabel; /** * Constructs a new command * * @param root * - Model root for getting the listeners * @param modelObjToRefresh * - Changed model object */ public AbstractNotificationOperation(final IModelRoot root, final IModelObject modelObjToRefresh, final String operationLabel) { this(root, new IModelObject[] { modelObjToRefresh }, operationLabel); } /** * Constructs a new command * * @param root * - Model root for getting the listeners * @param modelObject * - Changed model objects */ public AbstractNotificationOperation(final IModelRoot root, final IModelObject[] modelObjsToRefresh, final String operationLabel) { super(root.getEnv().getEditingDomain(), operationLabel); this.modelObjects = modelObjsToRefresh == null ? new IModelObject[0] : modelObjsToRefresh; this.modelObject = modelObjects.length > 0 ? modelObjects[0] : null; this.root = root; this.operationLabel = operationLabel; initializeOperationOptions(); } /** * Utility method, responsible for the operation options initialization */ protected void initializeOperationOptions() { final Map<Object, Object> options = new HashMap<Object, Object>(); options.put(Transaction.OPTION_NO_VALIDATION, Boolean.TRUE); options.put(Transaction.OPTION_NO_UNDO, Boolean.TRUE); setOptions(options); } @Override protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException { return run(monitor, info); } public abstract IStatus run(IProgressMonitor monitor, IAdaptable info) throws ExecutionException; public boolean shouldNotifyOnDidCommit() { return true; } @Override protected void didCommit(final Transaction transaction) { super.didCommit(transaction); if (transaction.getParent() != null) { transferNotificationsToParent(transaction); } } protected void transferNotificationsToParent(final Transaction transaction) { final List<Notification> currentNotifications = ((TransactionImpl) transaction).getNotifications(); final TransactionImpl parent = (TransactionImpl) ((TransactionImpl) transaction).getParent(); if (parent != null) { final List<Notification> parentNotifications = parent.getNotifications(); for (final Notification currents : currentNotifications) { if (!parentNotifications.contains(currents)) { parent.add(currents); } } } } @Override protected void didRedo(final Transaction tx) { super.didRedo(tx); processPostUndoRedo(tx); } @Override protected void didUndo(final Transaction tx) { super.didUndo(tx); processPostUndoRedo(tx); } private void processPostUndoRedo(final Transaction tx) { if (tx.getParent() != null) { transferNotificationsToParent(tx); } } public IModelRoot getModelRoot() { return root; } public IModelObject[] getModelObjects() { return this.modelObjects; } public IModelObject getModelObject() { return modelObject; } }