blob: adf0e96dbeabea109fae0f7734830b96503bed56 [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 v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Ansgar Radermacher ansgar.radermacher@cea.fr
*
*****************************************************************************/
package org.eclipse.papyrus.robotics.ros2.reverse.utils;
import java.io.IOException;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.papyrus.designer.languages.common.base.StringConstants;
import org.eclipse.papyrus.designer.transformation.base.utils.ModelManagement;
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.robotics.core.utils.FileExtensions;
import org.eclipse.papyrus.robotics.profile.robotics.commobject.CommunicationObject;
import org.eclipse.papyrus.robotics.ros2.reverse.Activator;
import org.eclipse.papyrus.uml.diagram.wizards.command.InitFromTemplateCommand;
import org.eclipse.papyrus.uml.diagram.wizards.command.NewPapyrusModelCommand;
import org.eclipse.papyrus.uml.tools.utils.PackageUtil;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.uml2.uml.DataType;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.UMLPackage;
public class ReverseUtils {
/**
* Create a new message package
*
* @param folder
* the folder in which a new model will be created
* @param msgPkgName
* the ROS2 message package name
* @return the root package of the created model
*/
@SuppressWarnings("nls")
public static Package createMsgPackage(IFolder folder, String msgPkgName) {
try {
ServicesRegistry registry = new ExtensionServicesRegistry(org.eclipse.papyrus.infra.core.Activator.PLUGIN_ID);
registry.startServicesByClassKeys(ModelSet.class);
ModelSet modelSet = registry.getService(ModelSet.class);
TransactionalEditingDomain domain = modelSet.getTransactionalEditingDomain();
URI newURI = getURIfromFolder(folder, msgPkgName);
RecordingCommand command = new NewPapyrusModelCommand(modelSet, newURI);
domain.getCommandStack().execute(command);
InitFromTemplateCommand tp = new InitFromTemplateCommand(modelSet.getTransactionalEditingDomain(), modelSet,
"org.eclipse.papyrus.robotics.wizards",
"templates/robotics.servicedef.uml", "templates/robotics.servicedef.notation", "templates/robotics.servidedef.di");
domain.getCommandStack().execute(tp);
modelSet.save(new NullProgressMonitor());
registry.disposeRegistry();
Resource r = ModelManagement.getResourceSet().getResource(newURI, true);
Package pkg = (Package) r.getContents().get(0);
pkg.setName(msgPkgName);
setXmlID(pkg);
return pkg;
} catch (ServiceException | IOException e) {
Activator.log.error(e);
}
return null;
}
/*
* @param folder
* the folder in which a new model will be created
*
* @param msgPkgName
* the ROS2 message package name
*
* @return the URI the model representing a message package within a folder
*/
public static URI getURIfromFolder(IFolder folder, String msgPkgName) {
String path = folder.getProjectRelativePath() + StringConstants.SLASH + msgPkgName + FileExtensions.SERVICEDEF_UML;
return URI.createPlatformResourceURI(folder.getProject().getName() + StringConstants.SLASH + path, true);
}
/*
* @param pkg a UML2 package
*
* @param nestedName the name of a sub-package
*
* @return the created (or obtained) sub-package within the passed package
*/
public static Package getOrCreatePackage(Package pkg, String nestedName) {
Package nested = pkg.getNestedPackage(nestedName);
if (nested == null) {
nested = pkg.createNestedPackage(nestedName);
setXmlID(nested);
}
return nested;
}
/**
* Does the given service package already exist?
*
* @param folder
* the folder in which a new model will be created
* @param pathMapURIs
* a list of pathMapURIs to scan
* @param msgPkgName
* the ROS2 message package name
* @return true, if existing
*/
public static boolean existsAlready(IFolder folder, List<URI> pathMapURIs, String msgPkgName) {
String fileName = fileName(msgPkgName);
IFile file = folder.getFile(fileName);
if (file != null && file.exists()) {
return true;
}
// now check whether a file with the right name is accessible via a service definition
for (URI pathURI : pathMapURIs) {
if (pathURI.toString().endsWith(fileName)) {
return true;
}
}
return false;
}
/**
* Load a message package into the MM resourceSet.
*
* @param folder
* the folder in which a new model will be created
* @param pathMapURIs
* a list of pathMapURIs to scan
* @param msgPkgName
* the ROS2 message package name
* @return true, if successful
*/
public static boolean loadMessagePackage(IFolder folder, List<URI> pathMapURIs, String msgPkgName) {
String fileName = fileName(msgPkgName);
IFile file = folder.getFile(fileName);
if (file != null && file.exists()) {
URI uri = getURIfromFolder(folder, msgPkgName);
return ModelManagement.getResourceSet().getResource(uri, true) != null;
}
// now check whether a file with the right name is accessible via a service definition
for (URI pathURI : pathMapURIs) {
if (pathURI.toString().endsWith(fileName)) {
return ModelManagement.getResourceSet().getResource(pathURI, true) != null;
}
}
return false;
}
/**
* Return the file name of the model representing a message package
*
* @param msgPkgName
* the ROS2 message package name
* @return the file name
*/
public static String fileName(String msgPkgName) {
return msgPkgName + FileExtensions.SERVICEDEF_UML;
}
/**
* get or create a communication object
*
* @param pkg
* a UML package in which to search a communication object
* @param commObjects
* a list of communication objects. The new or obtained
* communication object will be added to the list
* @param name
* the name the communication object to get or create
* @return true, if the communication object existed already.
*/
public static boolean getOrCreateCommObject(Package pkg, List<DataType> commObjects, String name) {
DataType commObject = (DataType) pkg.getOwnedType(name);
if (commObject == null) {
commObject = (DataType) pkg.createOwnedType(name, UMLPackage.eINSTANCE.getDataType());
StereotypeUtil.apply(commObject, CommunicationObject.class);
setXmlID(commObject);
commObjects.add(commObject);
return true;
}
commObjects.add(commObject);
return false;
}
@SuppressWarnings("nls")
/**
* Write an XML id based on its name (without the top-level package name)
* @param ne
*/
public static void setXmlID(NamedElement ne) {
Package root = PackageUtil.getRootPackage(ne);
setXmlID(ne, "ID" + ne.getQualifiedName().replaceFirst(root.getName(), "").replaceAll(NamedElement.SEPARATOR, "_"));
}
/**
* Set the XML ID of an eObject
*
* @param eObject
* @param uniqueID
*/
public static void setXmlID(EObject eObject, String uniqueID) {
Resource eObjectRes = eObject.eResource();
if (eObjectRes instanceof XMLResource) {
XMLResource xmlResource = (XMLResource) eObjectRes;
xmlResource.setID(eObject, uniqueID);
}
}
}