blob: 03c03db0ba5915d5907e6eccd13d56b9cdea093b [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation 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
*
* Contributors:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.emf.type.core.commands;
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.core.runtime.Status;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.emf.core.util.PackageUtil;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.internal.EMFTypePlugin;
import org.eclipse.gmf.runtime.emf.type.core.internal.l10n.EMFTypeCoreMessages;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
/**
* Command to create a new model element.
*
* @author ldamus
*/
public class CreateElementCommand extends EditElementCommand {
/**
* The newly created element.
*/
private EObject newElement;
/**
* The element type to be created.
*/
private final IElementType elementType;
/**
* The containment feature in which the new element will be created.
*/
private EReference containmentFeature;
/**
* Status of the default element creation.
*/
private IStatus defaultElementCreationStatus;
/**
* Constructs a new element creation command for the <code>request</code>.
*
* @param request
* the element creation request
*/
public CreateElementCommand(CreateElementRequest request) {
super(request.getLabel(), null, request);
elementType = request.getElementType();
containmentFeature = request.getContainmentFeature();
}
protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
IAdaptable info)
throws ExecutionException {
// Do the default element creation
newElement = doDefaultElementCreation();
if (!getDefaultElementCreationStatus().isOK()) {
return new CommandResult(getDefaultElementCreationStatus());
}
// Configure the new element
ConfigureRequest configureRequest = createConfigureRequest();
ICommand configureCommand = elementType
.getEditCommand(configureRequest);
IStatus configureStatus = null;
if (configureCommand != null && configureCommand.canExecute()) {
configureStatus = configureCommand.execute(monitor, info);
}
// Put the newly created element in the request so that the
// 'after' commands have access to it.
getCreateRequest().setNewElement(newElement);
return (configureStatus == null) ?
CommandResult.newOKCommandResult(newElement) :
new CommandResult(configureStatus, newElement);
}
/**
* Creates the request to configure the new element.
*
* @return the request
*/
protected ConfigureRequest createConfigureRequest() {
ConfigureRequest configureRequest = new ConfigureRequest(
getEditingDomain(), newElement, getElementType());
// pass along the client context
configureRequest.setClientContext(getCreateRequest().getClientContext());
configureRequest.addParameters(getRequest().getParameters());
return configureRequest;
}
/**
* Subclasses should implement this to override the basic element creation.
*
* @return the new model element that has been created
*/
protected EObject doDefaultElementCreation() {
EObject result = null;
EReference containment = getContainmentFeature();
EClass eClass = getElementType().getEClass();
if (containment != null) {
EObject element = getElementToEdit();
if (element != null) {
result = EMFCoreUtil.create(element, containment, eClass);
}
}
IStatus status = (result != null) ? Status.OK_STATUS
: new Status(
Status.ERROR,
EMFTypePlugin.getPluginId(),
EMFTypeCoreMessages
.bind(
EMFTypeCoreMessages.createElementCommand_noElementCreated,
getElementType().getDisplayName()));
setDefaultElementCreationStatus(status);
return result;
}
/**
* Gets the status of the default element creation.
*
* @return the status
* @since 1.2
*/
protected IStatus getDefaultElementCreationStatus() {
if (defaultElementCreationStatus == null) {
return Status.OK_STATUS;
}
return defaultElementCreationStatus;
}
/**
* Sets the status of the default element creation.
*
* @param status
* the new status
* @since 1.2
*/
protected void setDefaultElementCreationStatus(IStatus status) {
this.defaultElementCreationStatus = status;
}
/**
* Initializes the container of the new element by asking the create to
* create the container, if necessary.
*/
protected EObject getElementToEdit() {
if (super.getElementToEdit() == null) {
CreateElementRequest request = (CreateElementRequest) getRequest();
setElementToEdit(request.createContainer());
}
return super.getElementToEdit();
}
/**
* Gets the EClass of the element to be edited.
*
* @return the EClass
*/
protected EClass getEClassToEdit() {
CreateElementRequest request = (CreateElementRequest) getRequest();
Object context = request.getEditHelperContext();
if (context instanceof EObject) {
return ((EObject) context).eClass();
} else {
IElementType type = ElementTypeRegistry.getInstance()
.getElementType(context);
if (type != null) {
return type.getEClass();
}
}
return null;
}
/**
* Gets the containment feature for the new element.
*
* @return the containment feature
*/
protected EReference getContainmentFeature() {
if (containmentFeature == null) {
EClass classToEdit = getEClassToEdit();
if (classToEdit != null) {
IElementType type = getElementType();
if (type != null && type.getEClass() != null) {
containmentFeature = PackageUtil.findFeature(classToEdit,
type.getEClass());
}
}
}
return containmentFeature;
}
/**
* Sets the containment feature for the new element.
*
* @param containmentFeature
* the containment feature for the new element
*/
protected void setContainmentFeature(EReference containmentFeature) {
this.containmentFeature = containmentFeature;
}
/**
* Gets the element type for the new element.
*
* @return the element type
*/
protected IElementType getElementType() {
return elementType;
}
/**
* Gets the create request.
*
* @return the create request
*/
public CreateElementRequest getCreateRequest() {
return (CreateElementRequest) getRequest();
}
public boolean canExecute() {
if (getEClassToEdit() == null) {
return false;
}
if (getContainmentFeature() != null) {
EClassifier eClassifier = getContainmentFeature().getEType();
boolean result = true;
if (eClassifier instanceof EClass) {
result = ((EClass) eClassifier).isSuperTypeOf(getElementType()
.getEClass());
}
result = result
&& PackageUtil.canContain(getEClassToEdit(),
getContainmentFeature(), getElementType()
.getEClass(), false);
return result && super.canExecute();
}
return false;
}
/**
* Gets the new element that was created by this command. Will be
* <code>null</code> if the command has not been executed.
*
* @return the new element
*/
public EObject getNewElement() {
return newElement;
}
}