/*******************************************************************************
* 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.
* Keshav Veerapaneni - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.command.emf.xsd;
import static org.eclipse.wst.sse.sieditor.model.utils.EmfXsdUtils.getXSDFactory;
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.xsd.XSDAttributeDeclaration;
import org.eclipse.xsd.XSDAttributeUse;
import org.eclipse.xsd.XSDComplexTypeContent;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDCompositor;
import org.eclipse.xsd.XSDConcreteComponent;
import org.eclipse.xsd.XSDElementDeclaration;
import org.eclipse.xsd.XSDModelGroup;
import org.eclipse.xsd.XSDNamedComponent;
import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDParticleContent;
import org.eclipse.xsd.XSDSimpleTypeDefinition;
import org.eclipse.xsd.XSDTypeDefinition;
import org.eclipse.wst.sse.sieditor.command.common.AbstractXSDNotificationOperation;
import org.eclipse.wst.sse.sieditor.model.Activator;
import org.eclipse.wst.sse.sieditor.model.api.IModelObject;
import org.eclipse.wst.sse.sieditor.model.api.IXSDModelRoot;
import org.eclipse.wst.sse.sieditor.model.i18n.Messages;
import org.eclipse.wst.sse.sieditor.model.impl.XSDFactory;
import org.eclipse.wst.sse.sieditor.model.utils.StatusUtils;
import org.eclipse.wst.sse.sieditor.model.xsd.api.IElement;
import org.eclipse.wst.sse.sieditor.model.xsd.api.ISchema;
import org.eclipse.wst.sse.sieditor.model.xsd.api.IStructureType;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.AbstractXSDComponent;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.Element;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.Schema;
import org.eclipse.wst.sse.sieditor.model.xsd.impl.StructureType;
/**
* Command for copying a local ElementDeclaration or an AttributeDeclaration
*
*
*/
public class CopyElementCommand extends AbstractXSDNotificationOperation {
private final IElement _element;
private IElement _copiedElement;
private final ISchema _targetSchema;
public CopyElementCommand(final IXSDModelRoot root, final IStructureType structure, final IElement element,
final ISchema targetSchema) {
super(root, structure, Messages.CopyElementCommand_copy_element_command_label);
this._element = element;
this._targetSchema = targetSchema;
}
@Override
public IStatus run(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
final StructureType structureType = (StructureType) modelObject;
final XSDNamedComponent schemaComponent = structureType.getComponent();
final XSDElementDeclaration element;
final XSDTypeDefinition xsdType;
element = schemaComponent instanceof XSDElementDeclaration ? (XSDElementDeclaration) schemaComponent : null;
xsdType = element == null ? (XSDTypeDefinition) schemaComponent : element.getType();
XSDComplexTypeDefinition type = null;
if (null != element) {
final XSDTypeDefinition elementType = element.getAnonymousTypeDefinition();
if (element.isElementDeclarationReference() || null == elementType || elementType instanceof XSDSimpleTypeDefinition) {
final EnsureElementAnonymousTypeCommand command = new EnsureElementAnonymousTypeCommand(getModelRoot(), element);
IStatus status = getModelRoot().getEnv().execute(command);
if(!StatusUtils.canContinue(status)) {
return status;
}
type = command.getAnonymousType();
} else {
type = (XSDComplexTypeDefinition) elementType;
}
} else {
type = (XSDComplexTypeDefinition) xsdType;
}
final Schema schema = (Schema) structureType.getParent();
if (type == null) {
return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CopyElementCommand_msg_can_not_create_type_definition);
}
XSDComplexTypeContent content = type.getContent();
if (null == content || content instanceof XSDSimpleTypeDefinition) {
content = getXSDFactory().createXSDParticle();
XSDModelGroup particleContent = getXSDFactory().createXSDModelGroup();
((XSDModelGroup) particleContent).setCompositor(XSDCompositor.SEQUENCE_LITERAL);
((XSDParticle) content).setContent(particleContent);
type.eUnset(getXSDFactory().getXSDPackage().getXSDComplexTypeDefinition_Content());
type.eUnset(getXSDFactory().getXSDPackage().getXSDComplexTypeDefinition_ContentType());
type.eUnset(getXSDFactory().getXSDPackage().getXSDComplexTypeDefinition_BaseTypeDefinition());
type.eUnset(getXSDFactory().getXSDPackage().getXSDComplexTypeDefinition_Block());
type.eUnset(getXSDFactory().getXSDPackage().getXSDComplexTypeDefinition_DerivationMethod());
type.setContent(content);
type.setContentType(content);
}
final XSDParticle particle = (XSDParticle) content;
XSDParticleContent particleContent = particle.getContent();
if (null == particleContent) {
particleContent = getXSDFactory().createXSDModelGroup();
((XSDModelGroup) particleContent).setCompositor(XSDCompositor.SEQUENCE_LITERAL);
particle.setContent(particleContent);
}
final XSDModelGroup modelGroup = (XSDModelGroup) particleContent;
XSDConcreteComponent copiedComponent = null;
XSDNamedComponent namedComponent = null;
final XSDConcreteComponent component = _element.getComponent();
if (component instanceof XSDParticle) {
final XSDParticle elementParticle = (XSDParticle) component.cloneConcreteComponent(true, false);
modelGroup.getContents().add(elementParticle);
namedComponent = (XSDNamedComponent) elementParticle.getContent();
copiedComponent = elementParticle;
} else if (component instanceof XSDAttributeDeclaration) {
final XSDAttributeDeclaration attribute = (XSDAttributeDeclaration) component.cloneConcreteComponent(true, false);
XSDAttributeUse attributeUse = getXSDFactory().createXSDAttributeUse();
attributeUse.setContent(attribute);
type.getAttributeContents().add(attributeUse);
copiedComponent = attribute;
namedComponent = attribute;
}
IXSDModelRoot xsdModelRoot = XSDFactory.getInstance().createXSDModelRoot(type.getSchema());
_copiedElement = new Element(xsdModelRoot, copiedComponent, modelGroup, structureType, schema);
IModelObject modelObject = ((IXSDModelRoot) getModelRoot()).getSchema();
final CopyTypeCommand command = new CopyTypeCommand(getModelRoot(), modelObject,
(XSDNamedComponent) (component instanceof XSDParticle ? ((XSDParticle) component).getContent() : component),
_targetSchema, _element.getName());
command.updateReferences(namedComponent);
IStatus status = getModelRoot().getEnv().execute(command);
if (!StatusUtils.canContinue(status)) {
return status;
}
return Status.OK_STATUS;
}
public boolean canExecute() {
return !(null == modelObject || null == _targetSchema || null == _element);
}
public IElement getCopiedElement() {
return _copiedElement;
}
}