| /******************************************************************************* |
| * |
| * 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; |
| } |
| |
| } |