blob: a458ffe62d7fec352acaaad19b60d5ba83ddaec2 [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.codegen.cpp.component;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.papyrus.designer.languages.common.base.file.IFileExists;
import org.eclipse.papyrus.designer.languages.cpp.codegen.transformation.CppModelElementsCreator;
import org.eclipse.papyrus.designer.transformation.base.utils.TransformationException;
import org.eclipse.papyrus.designer.transformation.core.transformations.ExecuteTransformationChain;
import org.eclipse.papyrus.designer.transformation.core.transformations.TransformationContext;
import org.eclipse.papyrus.designer.languages.common.base.file.IPFileSystemAccess;
import org.eclipse.papyrus.robotics.codegen.common.component.CodeSkeleton;
import org.eclipse.papyrus.robotics.ros2.codegen.cpp.utils.ProjectTools;
import org.eclipse.papyrus.uml.tools.utils.PackageUtil;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.xtext.xbase.lib.Exceptions;
/**
* A variant of the CppModelElementsCreator that enables putting putting
* skeletons into a separate skeleton folder
* TODO: move into designer?
*/
public class RoboticsCppCreator extends CppModelElementsCreator {
String skeletonFolder;
/**
* the folder for the (user) src code
*/
String userSrcFolder;
Package currentModel;
/**
* Constructor.
*
* @param fileAccess
* the file system access
* @param skeletonFolder
* the folder, into which skeletons should be placed (with a trailing "/")
*/
public RoboticsCppCreator(IProject project, IPFileSystemAccess fileAccess, String skeletonFolder, String userSrcFolder) {
super(project, fileAccess, null);
this.skeletonFolder = skeletonFolder;
this.userSrcFolder = userSrcFolder;
}
@Override
public void createPackageableElement(PackageableElement element, IProgressMonitor monitor) {
currentModel = PackageUtil.getRootPackage(element);
super.createPackageableElement(element, monitor);
}
/**
* If the file is a skeleton file and the user source code file (in src) does not exist yet, generate this
* file as well.
*
* @see org.eclipse.papyrus.designer.languages.cpp.codegen.transformation.CppModelElementsCreator#generateFile(java.lang.String, java.lang.String)
*
* @param fileName
* the file to generate
* @param content
*/
@Override
protected void generateFile(String fileName, String content) {
// don't generate, if indexer is active (non-idle)
if (TransformationContext.monitor.isCanceled()) {
// use xtend trick to throw a non-declared exception
throw Exceptions.sneakyThrow(new TransformationException(ExecuteTransformationChain.USER_CANCEL));
}
ProjectTools.waitForCDT();
TransformationContext.monitor.subTask("generate file " + fileName); //$NON-NLS-1$
TransformationContext.monitor.worked(1);
if (currentModel != null) {
content = ComponentHeader.getHeader(currentModel) + content;
}
if (fileName.startsWith(skeletonFolder)) {
String srcFileName = fileName.replaceFirst(skeletonFolder, userSrcFolder);
if (fileSystemAccess instanceof IFileExists) {
IFileExists existsFSA = (IFileExists) fileSystemAccess;
if (!existsFSA.existsFile(srcFileName)) {
super.generateFile(srcFileName, content);
}
}
}
super.generateFile(fileName, content);
}
/**
* @see org.eclipse.papyrus.designer.languages.cpp.codegen.transformation.CppModelElementsCreator#getFileName(org.eclipse.uml2.uml.NamedElement)
*
* @param element
* @return the filename prefixed either with the "normal" src-gen or the skeleton folder
*/
@Override
public String getFileName(NamedElement element) {
// TODO: name based check not clean and possibly error prone
if (element.getName() != null && element.getName().endsWith(CodeSkeleton.POSTFIX)) {
return skeletonFolder + locStrategy.getFileName(element);
} else {
return super.getFileName(element);
}
}
}