blob: b1027f11aa6cd7a313e8c7cb844474a9460b40cc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 EfficiOS Inc., Philippe Proulx
*
* 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
*******************************************************************************/
package org.eclipse.tracecompass.internal.provisional.analysis.lami.core.module;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.function.Predicate;
import org.eclipse.tracecompass.internal.analysis.lami.core.Activator;
import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.LamiConfigFileStrings;
import org.eclipse.tracecompass.internal.provisional.analysis.lami.core.ShellUtils;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
/**
* Factory which builds {@link LamiAnalysis} objects out of configuration
* files.
*
* @author Philippe Proulx
*/
public final class LamiAnalysisFactoryFromConfigFile {
private LamiAnalysisFactoryFromConfigFile() {}
private static String getProperty(Properties props, String propName) throws LamiAnalysisFactoryException {
String prop = props.getProperty(propName);
if (prop == null) {
throw new LamiAnalysisFactoryException(String.format("Cannot find \"%s\" property", propName)); //$NON-NLS-1$
}
prop = prop.trim();
if (prop.isEmpty()) {
throw new LamiAnalysisFactoryException(String.format("\"%s\" property cannot be empty", propName)); //$NON-NLS-1$
}
return prop;
}
/**
* Builds a {@link LamiAnalysis} object from an input stream providing the
* content of a configuration file.
* <p>
* The caller is responsible for opening and closing {@code inputStream}.
*
* @param inputStream
* Input stream for reading the configuration file; the stream is
* not closed by this method
* @param isUserDefined
* {@code true} if the analysis to build is user-defined
* @param appliesTo
* Predicate to use to check whether or not this analysis applies
* to a given trace
* @return Built {@link LamiAnalysis} object
* @throws LamiAnalysisFactoryException
* If something went wrong reading the input stream
*/
public static LamiAnalysis buildFromInputStream(InputStream inputStream, boolean isUserDefined,
Predicate<ITmfTrace> appliesTo) throws LamiAnalysisFactoryException {
final Properties props = new Properties();
// Load properties
try {
props.load(inputStream);
} catch (IOException e) {
throw new LamiAnalysisFactoryException(e);
}
// Get analysis' name and command
final String name = getProperty(props, LamiConfigFileStrings.PROP_NAME);
final String command = getProperty(props, LamiConfigFileStrings.PROP_COMMAND);
// Get individual arguments from command string
final List<String> args = ShellUtils.commandStringToArgs(command);
return new LamiAnalysis(name, isUserDefined, appliesTo, args);
}
/**
* Builds a {@link LamiAnalysis} object from a configuration file.
*
* @param configFilePath
* Configuration file path
* @param isUserDefined
* {@code true} if the analysis to build is user-defined
* @param appliesTo
* Predicate to use to check whether or not this analysis applies
* to a given trace
* @return Built {@link LamiAnalysis} object
* @throws LamiAnalysisFactoryException
* If something went wrong reading the file
*/
public static LamiAnalysis buildFromConfigFile(Path configFilePath, boolean isUserDefined,
Predicate<ITmfTrace> appliesTo) throws LamiAnalysisFactoryException {
try (final InputStream propsStream = Files.newInputStream(configFilePath)) {
return buildFromInputStream(propsStream, isUserDefined, appliesTo);
} catch (IOException e) {
throw new LamiAnalysisFactoryException(e);
}
}
/**
* Builds a list of {@link LamiAnalysis} objects from a directory containing
* configuration files.
*
* @param configDir
* Configuration directory containing the configuration files to
* load
* @param isUserDefined
* {@code true} if the analyses to build are user-defined
* @param appliesTo
* Predicate to use to check whether or not those analyses apply
* to a given trace
* @return List of built {@link LamiAnalysis} objects
* @throws LamiAnalysisFactoryException
* If something went wrong reading the directory
*/
public static List<LamiAnalysis> buildFromConfigDir(Path configDir, boolean isUserDefined,
Predicate<ITmfTrace> appliesTo) throws LamiAnalysisFactoryException {
final List<LamiAnalysis> analyses = new ArrayList<>();
try (final DirectoryStream<Path> directoryStream = Files.newDirectoryStream(configDir)) {
for (final Path path : directoryStream) {
try {
analyses.add(buildFromConfigFile(path, isUserDefined, appliesTo));
} catch (LamiAnalysisFactoryException e) {
Activator.instance().logWarning(String.format("Cannot load external analysis \"%s\"", path)); //$NON-NLS-1$
}
}
} catch (IOException e) {
throw new LamiAnalysisFactoryException(e);
}
return analyses;
}
}