blob: e9cf8b7d5d1e0892ce22bec0e4a626a097b2449d [file] [log] [blame]
/*******************************************************************************
*
* Copyright (c) 2018, 2020 Robert Bosch GmbH.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.app4mc.transformation;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Hashtable;
import java.util.Properties;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(service = TransformationProcessor.class)
public class TransformationProcessor {
private static final Logger LOG = LoggerFactory.getLogger(TransformationProcessor.class);
@Reference
ConfigurationAdmin configAdmin;
/**
* Start the transformation with the configuration provided by the given
* {@link File}.
*
* @param propertiesFile The properties file that contains the necessary
* transformation configuration.
*/
public void startTransformation(File propertiesFile) {
startTransformation(propertiesFile, null);
}
/**
* Start the transformation with the configuration provided by the given
* {@link File}.
*
* @param propertiesFile The properties file that contains the necessary
* transformation configuration.
* @param workingDirectory The working directory to resolve relative paths for
* values in the properties file.
*/
public void startTransformation(File propertiesFile, String workingDirectory) {
try {
Properties inputParameters = getInputParameter(propertiesFile, workingDirectory);
startTransformation(inputParameters, false);
} catch (IOException e) {
LOG.error("Error in extracting properties from provided input file", e);
}
}
/**
* Start the transformation with the provided configuration properties. The
* following parameters should be specified:
* <ul>
* <li>input_models_folder - the folder with the model files that should be
* transformed</li>
* <li>m2m_output_folder - the folder where the m2m transformation results
* should be generated</li>
* <li>m2t_output_folder - the folder where the m2t transformation results
* should be generated</li>
* <li>log_file - the name of the session log file</li>
* <li>m2mTransformers - comma separated key list of m2m transformations that
* should be executed</li>
* <li>m2tTransformers - comma separated key list of m2t transformations that
* should be executed</li>
* </ul>
*
* @param inputParameters The properties with the necessary configuration
* parameter.
*/
public void startTransformation(Properties inputParameters) {
startTransformation(inputParameters, true);
}
/**
* Start the transformation with the provided configuration properties. The
* following parameters should be specified:
* <ul>
* <li>input_models_folder - the folder with the model files that should be
* transformed</li>
* <li>m2m_output_folder - the folder where the m2m transformation results
* should be generated</li>
* <li>m2t_output_folder - the folder where the m2t transformation results
* should be generated</li>
* <li>log_file - the name of the session log file</li>
* <li>m2mTransformers - comma separated key list of m2m transformations that
* should be executed</li>
* <li>m2tTransformers - comma separated key list of m2t transformations that
* should be executed</li>
* </ul>
*
* @param inputParameters The properties with the necessary configuration
* parameter.
*/
private void startTransformation(Properties inputParameters, boolean harmonize) {
if (inputParameters != null) {
try {
Object workingDirectoryPath = inputParameters.get("workingDirectory");
File rootDir = null;
if (workingDirectoryPath !=null && !workingDirectoryPath.toString().trim().equals("")) {
rootDir = new File(workingDirectoryPath.toString());
}
Properties params = harmonize ? harmonizeInputParameter(inputParameters, rootDir) : inputParameters;
Hashtable<String, Object> dictionaryForConfiguration = new Hashtable<>();
for (String name : params.stringPropertyNames()) {
String value = params.getProperty(name);
dictionaryForConfiguration.put(name, value);
}
String name = params.getProperty(ServiceConstants.SESSION_ID);
if (name == null) {
name = "single";
dictionaryForConfiguration.put(ServiceConstants.SESSION_ID, name);
}
try {
// ensure that a session is not triggered twice
String filter = "(&(service.pid=" + ServiceConstants.SESSION_CONFIGURATION_PID + "~" + name + ")"
+ "(service.factoryPid=" + ServiceConstants.SESSION_CONFIGURATION_PID + "))";
Configuration[] existing = this.configAdmin.listConfigurations(filter);
if (existing == null || existing.length == 0) {
// create the configuration to trigger the activation of transformation components and the transformation
// this way we start a new session to get new transformer instances
Configuration configuration = this.configAdmin.getFactoryConfiguration(ServiceConstants.SESSION_CONFIGURATION_PID, name, "?");
configuration.update(dictionaryForConfiguration);
}
} catch (InvalidSyntaxException e) {
LOG.error("Error in retrieving existing session configurations", e);
}
} catch (IOException e) {
}
} else {
LOG.error(
"ERROR !! Unable to start transformation as required parameters are not set in input properties file");
}
}
private Properties getInputParameter(File propertiesFile, String workingDirectory) throws IOException {
Properties properties = new Properties();
properties.load(new FileInputStream(propertiesFile));
File workDir = null;
// if a working directory is provided as argument, it should override a possible value in the properties file
if (workingDirectory != null && !workingDirectory.isEmpty()) {
properties.put("workingDirectory", workingDirectory);
workDir = new File(workingDirectory);
} else {
// if no working directory value was provided as argument, check if there is a value in the properties
String dir = properties.getProperty("workingDirectory");
if (dir != null && !dir.isEmpty()) {
workDir = new File(dir);
}
}
if (workDir == null) {
// if no working directory is provided as argument and not in the properties, use the parent of the properties file
workDir = propertiesFile.getParentFile();
//if properties doesn't contain 'workingDirectory' and command line parameter is also not specified, then add parent of properties file -> in properties as value for 'workingDirectory'
if(!properties.contains("workingDirectory")) {
properties.put("workingDirectory", workDir.getPath());
}
}
return harmonizeInputParameter(properties, workDir);
}
private Properties harmonizeInputParameter(Properties properties, File rootFolder) {
// Now checking if the user has specified absolute paths in the properties file
Object inputModelsFolder = properties.get("input_models_folder");
Object outputFolder = properties.get("output_folder");
File inputFile = null;
if (inputModelsFolder != null) {
String path = inputModelsFolder.toString();
inputFile = new File(path);
if (inputFile.exists()) {
// the file exists so we can simply use the specified path
properties.put("input_models_folder", path);
} else if (rootFolder != null) {
// the file seems to not exist, try to evaluate with the provided parent
inputFile = new File(rootFolder, path);
if (inputFile.exists()) {
properties.put("input_models_folder", inputFile.getAbsolutePath());
}
}
} else {
throw new IllegalArgumentException("'input_models_folder' parameter needs to be set");
}
if (inputFile == null || !inputFile.exists()) {
throw new IllegalArgumentException("'input_models_folder' doesn't seem to exist. Please check configuration of 'input_models_folder' and optional 'workingDirectory'.");
}
if (rootFolder == null) {
rootFolder = inputFile.getParentFile();
}
if (outputFolder != null) {
// check for generic output folder setting and derive needed values
Path outputFolderPath = Paths.get(outputFolder.toString());
properties.put("m2m_output_folder", Paths.get(outputFolderPath.toString(), "m2m_output_models").toString());
properties.put("m2t_output_folder", Paths.get(outputFolderPath.toString(), "m2t_output_text_files").toString());
properties.put("log_file", Paths.get(outputFolderPath.toString(), "transformation.log").toString());
}
Object m2m_outputModelsFolder = properties.get("m2m_output_folder");
Object m2t_output_folder = properties.get("m2t_output_folder");
Object logFile = properties.get("log_file");
// check for separate values
if (m2m_outputModelsFolder != null) {
String path = m2m_outputModelsFolder.toString();
String newPath = new File(path).isAbsolute()
? path
: new File(rootFolder, path).getAbsolutePath();
properties.put("m2m_output_folder", newPath);
} else{
throw new IllegalArgumentException("'m2m_output_folder' parameter needs to be set");
}
if (m2t_output_folder != null) {
String path = m2t_output_folder.toString();
String newPath = new File(path).isAbsolute()
? path
: new File(rootFolder, path).getAbsolutePath();
properties.put("m2t_output_folder", newPath);
} else {
throw new IllegalArgumentException("'m2t_output_folder' parameter needs to be set");
}
if (logFile != null) {
String path = logFile.toString();
String newPath = new File(path).isAbsolute()
? path
: new File(rootFolder, path).getAbsolutePath();
properties.put("log_file", newPath);
}
return properties;
}
}