blob: fb74d993f12e4ec32adfb22553b97d948e7dc4d5 [file] [log] [blame]
/*****************************************************************************
* Copyright (c) 2019, 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:
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - bug 569382
*****************************************************************************/
package org.eclipse.papyrus.model2doc.core.generatorconfiguration.operations;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osgi.util.NLS;
import org.eclipse.papyrus.model2doc.core.generatorconfiguration.IDocumentGeneratorConfiguration;
import org.eclipse.papyrus.model2doc.core.generatorconfiguration.IDocumentStructureGeneratorConfiguration;
import org.eclipse.papyrus.model2doc.core.generatorconfiguration.internal.Activator;
import org.osgi.framework.Bundle;
/**
* Utility class for the operations of GeneratorConfiguration metamodel
*/
public class GeneratorConfigurationOperations {
private static final String SLASH = "/"; //$NON-NLS-1$
private static final String UNDERSCORE = "_"; //$NON-NLS-1$
private static final String FILE_PREFIX = "file:/"; //$NON-NLS-1$
/**
*
* @param generatorConfiguration
* a generatorConfiguration element
* @param fileExtension
* the extension file
* @param optionalVersionSuffix
* a string representing the version of the generated document structure or <code>null</code>
* @return
* the path of the document structure. The returned path, will be a string starting with platform:/resource/
*/
public static final URI getDocumentStructureFileEcoreURI(final IDocumentStructureGeneratorConfiguration generatorConfiguration, final String fileExtension, final String optionalVersionSuffix) {
final String folderName = generatorConfiguration.getStructureFolder();
final StringBuilder documentNameBuilder = new StringBuilder(generatorConfiguration.getDocumentName());
if (null != optionalVersionSuffix && false == optionalVersionSuffix.isEmpty()) {
documentNameBuilder.append(UNDERSCORE);
documentNameBuilder.append(optionalVersionSuffix);
}
URI uri = URI.createURI(folderName);
final String scheme = uri.scheme(); // Windows C: for example
if (null != scheme && false == scheme.isEmpty()) {
throw new UnsupportedOperationException("A such path for DocumentStructure is not supported: " + uri); //$NON-NLS-1$
}
if (false == uri.isPlatform()) {
// we convert a local URI as platform resource URI
final String projectName = generatorConfiguration.eResource().getURI().segment(1);
uri = URI.createPlatformResourceURI(projectName, true);
for (final String current : folderName.split("/")) { //$NON-NLS-1$
uri = uri.appendSegment(current);
}
}
if (uri.isPlatform()) {
if (uri.isPlatformPlugin()) {
Activator.log.warn(NLS.bind("The path {0} must not be a platform path", uri.toString())); //$NON-NLS-1$
return null;
}
return uri.appendSegment(documentNameBuilder.toString()).appendFileExtension(fileExtension);
}
return null;
}
/**
*
* @param configuration
* the document generator configuration
* @param fileExtension
* the file extension used to create the file
* @return
* the file uri as local path (in C:/ for windows), prefixed with file:/
*/
public static final String getDocumentFileLocalPath(final IDocumentGeneratorConfiguration configuration, final String fileExtension) {
final String projectName;
if (null == configuration.eResource()) {
// TODO remove this test, when first version of generation will be deleted
projectName = null;
} else if (null == configuration.eResource().getURI() || configuration.eResource().getURI().segmentCount() < 1) {
throw new UnsupportedOperationException("This method doesn't work with DefaultDocumentGeneratorConfiguration which are not saved in a resource"); //$NON-NLS-1$
} else {
// the first segment is the Eclipse project name
projectName = configuration.eResource().getURI().segment(1);
}
return buildLocalPath(projectName, configuration.getDocumentFolder(), configuration.getDocumentName(), fileExtension);
}
/**
*
* @param configuration
* the document structure generator configuration
* @param imageExtension
* the image extension used to create the file
* @return
* the file uri as local path (in C:/ for windows), prefixed with file:/
* if the imageName contains whitespace, these whitespace will be removed
*/
public static final String getImageFileLocalPath(final IDocumentStructureGeneratorConfiguration configuration, final String imageName, final String imageExtension) {
final String projectName;
// remove whitespace
final String imageNameToUse = imageName.replaceAll("\\s+", ""); //$NON-NLS-1$ //$NON-NLS-2$
if (null == configuration.eResource() || null == configuration.eResource().getURI() || configuration.eResource().getURI().segmentCount() < 1) {
throw new UnsupportedOperationException("This method doesn't work with DefaultDocumentStructureGeneratorConfiguration which are not saved in a resource"); //$NON-NLS-1$
} else {
// the first segment is the Eclipse project name
projectName = configuration.eResource().getURI().segment(1);
}
return buildLocalPath(projectName, configuration.getImageFolder(), imageNameToUse, imageExtension);
}
/**
*
* @param projectName
* the name of the project in the workspace
* @param folderPath
* the path of the target folder
* @param fileName
* the name of the file
* @param fileExtension
* the extension of the file
* @return
* the file uri as local path (in C:/ for windows), prefixed with file:/
*
*/
private static final String buildLocalPath(final String projectName, final String folderPath, final String fileName, final String fileExtension) {
URI uri = URI.createURI(folderPath);
final String scheme = uri.scheme(); // Windows C: or platform for example
if (false == uri.isPlatform() && null != scheme && false == scheme.isEmpty()) {
URI newURI = URI.createFileURI(folderPath);
newURI = newURI.appendSegment(fileName).appendFileExtension(fileExtension);
return newURI.toString();
}
if (false == uri.isPlatform()) {
// we convert a local URI as platform resource URI
if (folderPath.contains(SLASH)) {// appendSegment doesn't work, when the string contains "/"
uri = URI.createPlatformResourceURI(projectName, true).appendSegments(folderPath.split(SLASH));
} else {
uri = URI.createPlatformResourceURI(projectName, true).appendSegment(folderPath);
}
}
if (uri.isPlatform()) {
if (uri.isPlatformPlugin()) {
Activator.log.warn(NLS.bind("The path {0} must not be a platform path", uri.toString())); //$NON-NLS-1$
return null;
}
uri = uri.appendSegment(fileName).appendFileExtension(fileExtension);
}
final IPath path = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))).getLocation();
// here, the special char must not be encoded
// for example we want a real space instead %20
final StringBuilder builder = new StringBuilder();
builder.append(FILE_PREFIX);
builder.append(path.toPortableString());
return builder.toString();
}
/**
*
* @param configuration
* the document structure generator configuration
* @return
* the image folder URI or <code>null</code>
*/
private static final URI getImageFolderURI(final IDocumentStructureGeneratorConfiguration configuration) {
final String projectName;
if (null == configuration.eResource() || null == configuration.eResource().getURI() || configuration.eResource().getURI().segmentCount() < 1) {
throw new UnsupportedOperationException("This method doesn't work with DefaultDocumentStructureGeneratorConfiguration which are not saved in a resource"); //$NON-NLS-1$
} else {
// the first segment is the Eclipse project name
projectName = configuration.eResource().getURI().segment(1);
}
return getImageFolderURI(projectName, configuration.getImageFolder());
}
/**
*
* @param projectName
* the project name
* @param folderPath
* the folder path
* @return
* the image folder URI or <code>null</code>
*/
private static final URI getImageFolderURI(final String projectName, final String folderPath) {
URI uri = URI.createURI(folderPath);
final String scheme = uri.scheme(); // Windows C: or platform for example
if (false == uri.isPlatform() && null != scheme && false == scheme.isEmpty()) {
return URI.createFileURI(folderPath);
}
if (false == uri.isPlatform()) {
// we convert a local URI as platform resource URI
if (folderPath.contains(SLASH)) {// appendSegment doesn't work, when the string contains "/"
uri = URI.createPlatformResourceURI(projectName, true).appendSegments(folderPath.split(SLASH));
} else {
uri = URI.createPlatformResourceURI(projectName, true).appendSegment(folderPath);
}
}
if (uri.isPlatform()) {
if (uri.isPlatformPlugin()) {
Activator.log.warn(NLS.bind("The path {0} must not be a platform path", uri.toString())); //$NON-NLS-1$
return null;
}
}
return uri;
}
/**
*
* @param configuration
* the configuration used to generate the document structure
* @return
* a collection of project name to refresh after the generation
*/
public static final Collection<String> getWorkspaceProjectToRefresh(final IDocumentStructureGeneratorConfiguration configuration) {
final Collection<String> projectsToRefresh = new HashSet<>();
// 1. get the project name for the pds file
URI uri = getDocumentStructureFileEcoreURI(configuration, "dummyExtension", null); //$NON-NLS-1$
if (null != uri) {
// get the project output for pds
if (uri.isPlatformResource() && uri.segmentCount() > 2) {
projectsToRefresh.add(uri.segment(1));// 1 is the project name
}
}
// 2. get the project name for the image folder
uri = getImageFolderURI(configuration);
if (null != uri) {
// get the project output for pds
if (uri.isPlatformResource() && uri.segmentCount() > 2) {
projectsToRefresh.add(uri.segment(1));// 1 is the project name
}
}
return projectsToRefresh;
}
/**
*
* @param configuration
* the generator configuration
* @return
* the file uri as local path (in C:/ for windows), prefixed with file:/
*/
public static final String getTemplateFilePathInLocalPath(final IDocumentGeneratorConfiguration configuration) {
return getFilePathInLocalPath(configuration, configuration.getTemplateFile());
}
/**
*
* @param eobject
* an eobject
* @param filePath
* a path to convert , the path can be a platform:/plugin, and platform:/resource a just a string. In this case we build a path from the location of the EObject given in parameter
* @return
* the file uri as local path (in C:/ for windows), prefixed with file:/
*
*/
public static final String getFilePathInLocalPath(final EObject eobject, final String filePath) {
if (null == filePath || filePath.isEmpty()) {
return null;
}
URI templateURI = URI.createURI(filePath);
final String scheme = templateURI.scheme(); // Windows C: or platform for example
if (false == templateURI.isPlatform() && null != scheme && false == scheme.isEmpty()) {
return URI.createFileURI(filePath).toString();// it add the file:/ before the path
}
String res = convertToLocalPath(eobject, filePath);
if (res != null) {
return URI.createFileURI(res).toString();
}
return null;
}
/**
*
* @param anEobject
* an EObject, attached to a resource
* @param path
* a path to convert , the path can be a platform:/plugin, and platform:/resource a just a string. In this case we build a path from the location of the EObject given in parameter
* @return
* <code>null</code> string if we can't resolved it, or the expected path (in C:/ for example, for windows System)
*/
private static final String convertToLocalPath(final EObject anEobject, final String path) {
URI uri = URI.createURI(path, true);
if (false == uri.isPlatform()) {
Assert.isTrue(null != anEobject.eResource(), "The EObject argument must be attached to a Resource"); //$NON-NLS-1$
// it is a local URI
final URI documentURI = anEobject.eResource().getURI();
// generation from platform:/plugin/ is not supported
Assert.isTrue(documentURI.isPlatformResource());
final String projectName = documentURI.segmentsList().get(1);
URI templateURIPath = URI.createPlatformResourceURI(projectName, true);
uri = templateURIPath.appendSegments(uri.segments());
}
if (uri.isPlatformPlugin()) {
final List<String> segments = uri.segmentsList();
final String bundleId = segments.get(1);
final StringBuilder pathInBundle = new StringBuilder();
for (int i = 2; i < segments.size(); i++) {
pathInBundle.append(segments.get(i));
if (i < segments.size() - 1) {
pathInBundle.append("/"); //$NON-NLS-1$
}
}
return getFileBundlePathToLocalPath(bundleId, pathInBundle.toString());
} else if (uri.isPlatformResource()) {
final IPath res = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri.toPlatformString(true))).getLocation();
return res.toPortableString();
}
return null;
}
/**
*
* @param bundleId
* the ID of a bundle
* @param filePathInBundle
* the path in the bundle
* @return
* the full path of the file, conformed to the OS, or <code>null</code> if not found
*/
private static final String getFileBundlePathToLocalPath(final String bundleId, final String filePathInBundle) {
final Bundle bundle = Platform.getBundle(bundleId); // $NON-NLS-1$
if (null == bundle) {
Activator.log.warn(NLS.bind("The bundle {0} doesn't exist", bundleId)); //$NON-NLS-1$
return null;
}
final URL eclipseURL = FileLocator.find(bundle, new Path(filePathInBundle), null);
if (null == eclipseURL) {
Activator.log.warn(NLS.bind("The file {0} doesn't exist in the bundle {1}", filePathInBundle, bundleId)); //$NON-NLS-1$
return null;
}
String templateURL = null;
try {
URL fileURL = FileLocator.toFileURL(eclipseURL);
templateURL = fileURL.toString();
templateURL = templateURL.replaceAll("file:/", ""); //$NON-NLS-1$ //$NON-NLS-2$
} catch (IOException e) {
Activator.log.error(NLS.bind("The URL {0} can't be converted", eclipseURL), e); //$NON-NLS-1$
}
return templateURL;
}
}