blob: 7d719b2214f3b53be5cd3658fa9a4eca936f7d13 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 THALES GLOBAL SERVICES.
* 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:
* Thales - initial API and implementation
*******************************************************************************/
package org.eclipse.amalgam.explorer.activity.internal.viewer.diagram.actions;
/**
*/
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import org.eclipse.amalgam.explorer.activity.ActivityExplorerActivator;
import org.eclipse.amalgam.explorer.activity.api.editor.pages.helper.StringHelper;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.AbstractCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.sirius.business.api.dialect.DialectManager;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;
/**
* A command thats clone specified representations.<br>
* Warning, this command does not handle the transactional behavior.<br>
* Thus it must be executed within a "calling" transaction.
*
*/
public class CloneDiagramCommand extends AbstractCommand {
/**
* The representations to clone.
*/
private Collection<DRepresentation> _representations;
/**
* Cloned representations.
*/
private Collection<DRepresentation> _clones;
/**
* Clone life cycle listeners.
*/
private Collection<ICloneListener> _listeners;
/**
* Constructor.
*
* @param representations_p
*/
public CloneDiagramCommand(Collection<DRepresentation> representations_p) {
super(Messages.CloneDiagramCommand_0);
_representations = representations_p;
}
/**
* @see org.eclipse.emf.common.command.AbstractCommand#dispose()
*/
@Override
public void dispose() {
super.dispose();
if (null != _clones) {
_clones.clear();
_clones = null;
}
if (null != _listeners) {
_listeners.clear();
_listeners = null;
}
if (null != _representations) {
_representations = null;
}
}
/**
* Add a clone life cycle listener.
*
* @param listener_p
*/
public void addCloneListener(ICloneListener listener_p) {
if (null == listener_p) {
return;
}
// Lazy allocation.
if (null == _listeners) {
_listeners = new HashSet<ICloneListener>(1);
}
// Add listener.
_listeners.add(listener_p);
}
/**
* Remove a registered clone life cycle listener.
*
* @param listener_p
*/
public void removeCloneListener(ICloneListener listener_p) {
if ((null == _listeners) || (null == listener_p)) {
return;
}
// Remove listener.
_listeners.remove(listener_p);
}
/**
* Send clone life cycle event.
*
* @param type_p
* @param clone_p
* @param session_p
*/
protected void notifyListeners(EventType type_p, DRepresentation clone_p, Session session_p) {
if ((null == _listeners) || _listeners.isEmpty()) {
return;
}
// Clone listeners collection.
ArrayList<ICloneListener> listeners = new ArrayList<ICloneListener>(_listeners);
// Call listeners.
for (ICloneListener listener : listeners) {
try {
if (EventType.ADD.equals(type_p)) {
listener.cloneCreated(clone_p, session_p);
} else if (EventType.REMOVE.equals(type_p)) {
listener.cloneAboutToBeRemoved(clone_p, session_p);
}
} catch (Exception exception_p) {
ActivityExplorerActivator.getDefault().sentToLogger("Unable to notify listeners !", IStatus.ERROR);
}
}
}
/**
* @see org.eclipse.emf.common.command.AbstractCommand#canUndo()
*/
@Override
public boolean canUndo() {
return (null != _clones) && (_clones.size() > 0);
}
/**
* @see org.eclipse.emf.common.command.Command#execute()
*/
public void execute() {
// Initialize clones list.
if (null == _clones) {
_clones = new ArrayList<DRepresentation>(0);
} else {
// Ensure emptiness.
if (_clones.size() > 0) {
_clones.clear();
}
}
// Copy all representations.
for (DRepresentation representation : _representations) {
if (representation instanceof DSemanticDecorator) {
// Get target semantic element.
EObject target = ((DSemanticDecorator) representation).getTarget();
// Get session.
Session session = SessionManager.INSTANCE.getSession(target);
// Copy representation.
DRepresentation copyRepresentation = DialectManager.INSTANCE.copyRepresentation(representation,
getCloneName(representation, session), session, null);
// Retain copied reference.
_clones.add(copyRepresentation);
// Notify listeners.
// S0024665 Not sure that is really needed as viewer has been
// already notified through the session
// notifyListeners(EventType.ADD, copyRepresentation, session);
} else {
ActivityExplorerActivator
.getDefault()
.getLog()
.log(new Status(IStatus.WARNING, ActivityExplorerActivator.ID,
"Clone is not supported for " + representation.getName())); //$NON-NLS-1$
}
}
}
/**
* Get clone name for specified representation.
*
* @param representation_p
* @return
*/
protected String getCloneName(DRepresentation representation_p, Session session_p) {
String message = "GET_NAME_PREFIX "; //$NON-NLS-1$
String cloneName = StringHelper.formatMessage(message, new Object[] { "", representation_p.getName() }); //$NON-NLS-1$
boolean cloneNameFound = false;
Collection<DRepresentation> allRepresentations = DialectManager.INSTANCE.getAllRepresentations(session_p);
int i = 1;
while (!cloneNameFound) {
boolean collision = false;
for (DRepresentation representation : allRepresentations) {
if (cloneName.equals(representation.getName())) {
collision = true;
break;
}
}
if (collision) {
cloneName = StringHelper.formatMessage(message, new Object[] { "" + ++i + ' ', //$NON-NLS-1$
representation_p.getName() });
}
cloneNameFound = !collision;
}
return cloneName;
}
/**
* @see org.eclipse.emf.common.command.AbstractCommand#prepare()
*/
@Override
protected boolean prepare() {
return true;
}
/**
* @see org.eclipse.emf.common.command.Command#redo()
*/
public void redo() {
execute();
}
/**
* @see org.eclipse.emf.common.command.AbstractCommand#undo()
*/
@Override
public void undo() {
// Delete all cloned representations.
for (DRepresentation representation : _clones) {
Session session = SessionManager.INSTANCE.getSession(((DSemanticDecorator) representation).getTarget());
// Notify listeners.
// S0024665 Not sure that is really needed as viewer has been
// already notified through the session
// notifyListeners(EventType.REMOVE, representation, session);
// Then execute delete.
DialectManager.INSTANCE.deleteRepresentation(representation, session);
}
// Clean clones collection.
_clones.clear();
}
/**
* Clone event type.
*
*/
protected enum EventType {
ADD, REMOVE
}
/**
* Clone listener.
*
*/
public interface ICloneListener {
/**
* Specified clone has just been added to specified session.
*
* @param clone_p
* @param session_p
*/
void cloneCreated(DRepresentation clone_p, Session session_p);
/**
* Specified clone is about to be removed from specified session.
*
* @param clone_p
* @param session_p
*/
void cloneAboutToBeRemoved(DRepresentation clone_p, Session session_p);
}
}