blob: c60ce4a783f43d0d05386d4c218cb8d40cceceb7 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2020 CEA LIST.
*
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Asma Smaoui (CEA LIST) asma.smaoui@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.aas.import2papyrus.transformations;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
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.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.services.ExtensionServicesRegistry;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.infra.emf.gmf.command.GMFtoEMFCommandWrapper;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.uml.service.types.element.UMLElementTypes;
import org.eclipse.papyrus.uml.tools.commands.ApplyStereotypeCommand;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.UMLPackage;
import io.shell.admin.aas._1._0.AasenvT;
import io.shell.admin.aas._1._0.AssetAdministrationShellT;
import io.shell.admin.aas._1._0.AssetAdministrationShellsT;
import io.shell.admin.aas._1._0.AssetT;
import io.shell.admin.aas._1._0.AssetsT;
import io.shell.admin.aas._1._0.DocumentRoot;
import io.shell.admin.aas._1._0.LangStringsT;
import io.shell.admin.aas._1._0.SubmodelT;
import io.shell.admin.aas._1._0.SubmodelsT;
import io.shell.admin.aas._1._0._0Package;
import io.shell.admin.aas._1._0.util._0Switch;
public class AAS2UMLSwitch extends _0Switch<EObject> {
public Map<EObject, EObject> transformedMap = new HashMap<>();
public Resource umlResource;
public Resource aasxResource;
public TransactionalEditingDomain domain;
List<EObject> umlElements = new ArrayList<>();
public Resource doTransform(Resource aasxResource, Resource umlResource) {
this.umlResource = umlResource;
this.aasxResource = aasxResource;
ServicesRegistry registry = createServicesRegistry();
this.domain = getTransactionalDomain(registry);
Iterator<EObject> iter = aasxResource.getAllContents();
// call transfo for all diagrams in the rhapsody project
while (iter.hasNext()) {
EObject eObject = (EObject) iter.next();
if (eObject instanceof DocumentRoot) {
AasenvT aasenv = ((DocumentRoot) eObject).getAasenv();
transform(aasenv);
}
}
// umlResource.getContents().addAll(umlElements);
try {
umlResource.save(null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// deleteTemporaryFiles();
return umlResource;
}
private Model getModel() {
Iterator<EObject> iter = umlResource.getAllContents();
// call transfo for all diagrams in the rhapsody project
while (iter.hasNext()) {
EObject eObject = (EObject) iter.next();
if (eObject instanceof Model) {
return (Model) eObject;
}
}
return null;
}
private EObject transform(EObject object) {
// first called for AssetT , doswitch calls the case AssetT ovverriden here
EObject ret = null;
if (object != null) {
ret = transformedMap.get(object);
if (ret == null) {
ret = (EObject) doSwitch(object);
}
}
return ret;
}
@Override
public EObject caseAasenvT(AasenvT object) {
// this is equivalent to Model root UML in UML
// model already created, so we only return the Model, do not create any thing
transform(object.getAssetAdministrationShells());
transform(object.getAssets());
transform(object.getSubmodels());
return null;
}
public EObject caseAssetAdministrationShellsT(AssetAdministrationShellsT object) {
EObject result = null;
if (object != null) {
result = (EObject) createPackage("AAS");
}
transformedMap.put(object, result);
umlElements.add(result);
// transform the contents of AASsT
EList<AssetAdministrationShellT> aasList = object.getAssetAdministrationShell();
if (aasList != null && !aasList.isEmpty())
for (AssetAdministrationShellT aas : aasList) {
transform(aas);
}
return result;
}
public EObject caseAssetAdministrationShellT(AssetAdministrationShellT object) {
// we create an AAS
EObject result = null;
if (object != null) {
result = (EObject) createAssetAdministrationShell(object);
}
transformedMap.put(object, result);
umlElements.add(result);
return result;
}
public EObject caseAssetsT(AssetsT object) {
// we create a Package for Assets
EObject result = null;
if (object != null) {
result = (EObject) createPackage("Assets");
}
transformedMap.put(object, result);
umlElements.add(result);
// transform the contents of AssetsT
EList<AssetT> assetList = object.getAsset();
if (assetList != null && !assetList.isEmpty())
for (AssetT asset : assetList) {
transform(asset);
}
return result;
}
public EObject caseAssetT(AssetT object) {
// we create an Asset
EObject result = null;
if (object != null) {
result = (EObject) createAsset(object);
}
transformedMap.put(object, result);
umlElements.add(result);
return result;
}
public EObject caseSubmodelsT(SubmodelsT object) {
// we create a Package for Submodels
EObject result = null;
if (object != null) {
result = (EObject) createPackage("Submodels");
}
transformedMap.put(object, result);
umlElements.add(result);
// transform the contents of Submodels
EList<SubmodelT> submodelList = object.getSubmodel();
if (submodelList != null && !submodelList.isEmpty())
for (SubmodelT submodel : submodelList) {
transform(submodel);
}
return result;
}
public EObject caseSubmodelT(SubmodelT object) {
// we create an Submodel
EObject result = null;
if (object != null) {
result = (EObject) createSubModel(object);
}
transformedMap.put(object, result);
umlElements.add(result);
return result;
}
private void setPropertyValue(Element target, Stereotype stereotype, String name, Object sourceValue) {
RecordingCommand setValueCommand = new RecordingCommand(domain) {
@Override
protected void doExecute() {
target.setValue(stereotype, name, sourceValue);
}
};
if (setValueCommand.canExecute())
setValueCommand.execute();
}
private Class createClass(String name, EObject container) {
// we create a Class
Class result = null;
if (container != null) {
CreateElementRequest request = new CreateElementRequest(domain, container, UMLElementTypes.CLASS);
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(container);
ICommand command = provider.getEditCommand(request);
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(command));
result = (Class) request.getNewElement();
SetRequest setRequest = new SetRequest((EObject) result, UMLPackage.eINSTANCE.getNamedElement_Name(), name);
ICommand command2 = provider.getEditCommand(setRequest);
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(command2));
}
return result;
}
private Package createPackage(String name) {
// we create a Package for Assets
Model model = getModel();
Package result = null;
// Model model = (Model) ((UMLResource) umlResource).getContents().get(0);
if (model != null) {
// create a Package and name it AAS
CreateElementRequest request = new CreateElementRequest(domain, model, UMLElementTypes.PACKAGE);
IElementEditService provider = ElementEditServiceUtils.getCommandProvider(model);
ICommand command = provider.getEditCommand(request);
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(command));
result = (Package) request.getNewElement();
SetRequest setRequest = new SetRequest((EObject) result, UMLPackage.eINSTANCE.getNamedElement_Name(), name);
ICommand command2 = provider.getEditCommand(setRequest);
domain.getCommandStack().execute(new GMFtoEMFCommandWrapper(command2));
}
return result;
}
private EObject createAsset(AssetT object) {
String name = object.getIdShort().getValue();
EObject container = getModel().getPackagedElement("Assets");
Class element = createClass(name, container);
// apply AAS::AssetAdministrationShell Stereotype on Class
Stereotype stereotype = element.getApplicableStereotype("AAS::Asset");
applyRequiredStereotype(element, stereotype);
// set the stereotype properties Values
setPropertiesValues(object, element);
return element;
}
private EObject createSubModel(SubmodelT object) {
String name = object.getIdShort().getValue();
EObject container = getModel().getPackagedElement("Submodels");
Class element = createClass(name, container);
// apply AAS::AssetAdministrationShell Stereotype on Class
Stereotype stereotype = element.getApplicableStereotype("AAS::Submodel");
applyRequiredStereotype(element, stereotype);
// set the stereotype properties Values
setPropertiesValues(object, element);
return element;
}
private EObject createAssetAdministrationShell(AssetAdministrationShellT object) {
String name = object.getIdShort().getValue();
EObject container = getModel().getPackagedElement("AAS");
Class element = createClass(name, container);
// apply AAS::AssetAdministrationShell Stereotype on Class
Stereotype stereotype = element.getApplicableStereotype("AAS::AssetAdministrationShell");
applyRequiredStereotype(element, stereotype);
// set the stereotype properties Values
setPropertiesValues(object, element);
return element;
}
private void applyRequiredStereotype(Element el, Stereotype stereotype) {
ApplyStereotypeCommand applyCommand = new ApplyStereotypeCommand(el, stereotype, domain);
domain.getCommandStack().execute(applyCommand);
}
private void setPropertiesValues(EObject source, Element target) {
Stereotype stereotype = target.getAppliedStereotypes().get(0);
EClass eCalss = source.eClass();
EList<EStructuralFeature> eAllAttributes = eCalss.getEAllStructuralFeatures();
CompositeTransactionalCommand command = new CompositeTransactionalCommand(domain, "Setting Sterteotype Propeties Value"); //$NON-NLS-1$
for (EStructuralFeature att : eAllAttributes) {
int attributeID = att.getFeatureID();
String name = getTargetPropertyFromSource(attributeID);
if (name != null) {
Property property = StereotypeUtil.getPropertyByName(stereotype,
name);
Object sourceValue = source.eGet(att);
Object getsourceValue;
if (name.equals("description") && sourceValue instanceof LangStringsT)
{
// get only the English description
getsourceValue= ((LangStringsT) sourceValue).getLangString().get(0).getValue();
}
else
{
getsourceValue =sourceValue;
}
if (getsourceValue!= null)
{
//Object sourceValue = StereotypeUtil.displayPropertyValue(stereotype, property, target, "");
AbstractTransactionalCommand c = new AbstractTransactionalCommand(domain, name, null) {
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1)
throws ExecutionException {
target.setValue(stereotype, name, getsourceValue);
return CommandResult.newOKCommandResult();
}
};
command.add(c);
}
}
}
// execute command
if (command!=null && command.canExecute())
try {
command.execute(null, null);
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String getTargetPropertyFromSource(int attributeID) {
switch (attributeID) {
case _0Package.ASSET_ADMINISTRATION_SHELL_T__CATEGORY:
return "category";
case _0Package.ASSET_ADMINISTRATION_SHELL_T__DESCRIPTION:
return "description";
default:
return null;
}
}
protected ServicesRegistry createServicesRegistry() {
ServicesRegistry result = null;
try {
result = new ExtensionServicesRegistry(org.eclipse.papyrus.infra.core.Activator.PLUGIN_ID);
} catch (ServiceException e) {
// couldn't create the registry? Fatal problem
e.printStackTrace();
}
try {
// have to create the model set and populate it with the DI model
// before initializing other services that actually need the DI
// model, such as the SashModel Manager service
result.startServicesByClassKeys(ModelSet.class);
} catch (ServiceException ex) {
// Ignore this exception: some services may not have been loaded,
// which is probably normal at this point
}
return result;
}
protected void initServicesRegistry(ServicesRegistry registry) throws ServiceException {
try {
registry.startRegistry();
} catch (ServiceException ex) {
// Ignore this exception: some services may not have been loaded,
// which is probably normal at this point
}
registry.getService(ModelSet.class);
}
public TransactionalEditingDomain getTransactionalDomain(ServicesRegistry registry) {
ResourceSet res = this.umlResource.getResourceSet();
TransactionalEditingDomain domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(res);
if (domain == null && registry != null) {
// have to create the model set and populate it with the DI model
// before initializing other services that actually need the DI
// model, such as the SashModel Manager service
try {
ModelSet modelSet = registry.getService(ModelSet.class);
// initServicesRegistry(registry);
domain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(modelSet);
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return domain;
}
}