/*
* Eoulsan development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public License version 2.1 or
* later and CeCILL-C. This should be distributed with the code.
* If you do not have a copy, see:
*
* http://www.gnu.org/licenses/lgpl-2.1.txt
* http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.txt
*
* Copyright for this code is held jointly by the Genomic platform
* of the Institut de Biologie de l'École normale supérieure and
* the individual authors. These should be listed in @author doc
* comments.
*
* For more information on the Eoulsan project and its aims,
* or to join the Eoulsan Google group, visit the home page
* at:
*
* http://outils.genomique.biologie.ens.fr/eoulsan
*
*/
package fr.ens.biologie.genomique.eoulsan.galaxytools;
import static fr.ens.biologie.genomique.eoulsan.galaxytools.elements.ToolElementFactory.newToolElement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import fr.ens.biologie.genomique.eoulsan.EoulsanException;
import fr.ens.biologie.genomique.eoulsan.core.Parameter;
import fr.ens.biologie.genomique.eoulsan.galaxytools.elements.ConditionalToolElement;
import fr.ens.biologie.genomique.eoulsan.galaxytools.elements.ToolElement;
import fr.ens.biologie.genomique.eoulsan.util.XMLUtils;
/**
* This class define static utils methods to extract data in Galaxy tool XML
* file.
* @author Sandrine Perrin
* @since 2.0
*/
public final class GalaxyToolXMLParserUtils {
/** The Constant ID_TAG. */
private static final String ID_TAG = "id";
/** The Constant NAME_TAG. */
private static final String NAME_TAG = "name";
/** The Constant VERSION_TAG. */
private static final String VERSION_TAG = "version";
/** The Constant TOOL_TAG. */
private static final String TOOL_TAG = "tool";
/** The Constant DESCRIPTION_TAG. */
private static final String DESCRIPTION_TAG = "description";
/** The Constant INTERPRETER_TAG. */
private static final String INTERPRETER_TAG = "interpreter";
/** The Constant DOCKER_IMAGE_TAG. */
private static final String DOCKER_IMAGE_TAG = "dockerimage";
/** The Constant COMMAND_TAG. */
private static final String COMMAND_TAG = "command";
/** The Constant PARAM_TAG. */
private static final String PARAM_TAG = "param";
/** The Constant INPUTS_TAG. */
private static final String INPUTS_TAG = "inputs";
/** The Constant DATA_TAG. */
private static final String DATA_TAG = "data";
/** The Constant OUTPUTS_TAG. */
private static final String OUTPUTS_TAG = "outputs";
/** The Constant CONDITIONAL. */
private static final String CONDITIONAL = "conditional";
/**
* Extract param element.
* @param parent the parent
* @param elementName the element name
* @return the map
* @throws EoulsanException the Eoulsan exception
*/
public static Map<String, ToolElement> extractParamElement(
final Element parent, final String elementName) throws EoulsanException {
final Map<String, Parameter> stepParameters = Collections.emptyMap();
return extractParamElement(parent, elementName, stepParameters);
}
public static Map<String, ToolElement> extractParamElement(
final Element parent, final String elementName,
final Map<String, Parameter> stepParameters) throws EoulsanException {
final Map<String, ToolElement> results = new HashMap<>();
// Extract all param tag
final List<Element> simpleParams =
extractChildElementsByTagName(parent, elementName);
for (final Element param : simpleParams) {
final ToolElement ptg = newToolElement(param);
if (!ptg.isFile()) {
ptg.setValues(stepParameters);
}
results.put(ptg.getName(), ptg);
}
return results;
}
/**
* Extract conditional param element.
* @param parent the parent
* @return the map
* @throws EoulsanException the Eoulsan exception
*/
public static Map<String, ToolElement> extractConditionalParamElement(
final Element parent) throws EoulsanException {
final Map<String, Parameter> stepParameters = Collections.emptyMap();
return extractConditionalParamElement(parent, stepParameters);
}
/**
* Extract conditional param element.
* @param parent the parent
* @param stepParameters the step parameters
* @return the map
* @throws EoulsanException the Eoulsan exception
*/
public static Map<String, ToolElement> extractConditionalParamElement(
final Element parent, final Map<String, Parameter> stepParameters)
throws EoulsanException {
final Map<String, ToolElement> results = new HashMap<>();
// Extract conditional element, can be empty
final List<Element> condParams = GalaxyToolXMLParserUtils
.extractChildElementsByTagName(parent, CONDITIONAL);
for (final Element param : condParams) {
final ConditionalToolElement tce = new ConditionalToolElement(param);
final ToolElement parameterSelect = tce.getToolElementSelect();
results.put(parameterSelect.getName(), parameterSelect);
// Set parameter
tce.setValues(stepParameters);
results.putAll(tce.getToolElementsResult());
}
return results;
}
/**
* Extract elements by tag name.
* @param doc the doc
* @param tagName the tag name
* @return the list
* @throws EoulsanException the Eoulsan exception
*/
public static List<Element> extractElementsByTagName(final Document doc,
final String tagName) throws EoulsanException {
return extractElementsByTagName(doc, tagName, -1);
}
/**
* Extract elements by tag name.
* @param doc the doc
* @param tagName the tag name
* @param expectedCount the expected count
* @return the list
* @throws EoulsanException the Eoulsan exception
*/
public static List<Element> extractElementsByTagName(final Document doc,
final String tagName, final int expectedCount) throws EoulsanException {
final List<Element> result = XMLUtils.getElementsByTagName(doc, tagName);
// Expected count available
if (expectedCount > 0) {
if (result.isEmpty()) {
throw new EoulsanException(
"Parsing tool XML file: no " + tagName + " tag found.");
}
if (result.size() != expectedCount) {
throw new EoulsanException("Parsing tool XML file: tag "
+ tagName + " invalid entry count found (expected " + expectedCount
+ " founded " + result.size() + ".");
}
}
if (result == null || result.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(result);
}
/**
* Extract elements by tag name.
* @param parent the parent
* @param tagName the tag name
* @return the list
* @throws EoulsanException the Eoulsan exception
*/
public static List<Element> extractElementsByTagName(final Element parent,
final String tagName) throws EoulsanException {
return extractElementsByTagName(parent, tagName, -1);
}
/**
* Extract elements by tag name.
* @param parent the parent
* @param tagName the tag name
* @param expectedCount the expected count
* @return the list
* @throws EoulsanException the Eoulsan exception
*/
public static List<Element> extractElementsByTagName(final Element parent,
final String tagName, final int expectedCount) throws EoulsanException {
final List<Element> result =
GalaxyToolXMLParserUtils.extractChildElementsByTagName(parent, tagName);
// Expected count available
if (expectedCount > 0) {
if (result.isEmpty()) {
throw new EoulsanException(
"Parsing tool XML file: no " + tagName + " tag found.");
}
if (result.size() != expectedCount) {
throw new EoulsanException("Parsing tool XML file: tag "
+ tagName + " invalid entry count found (expected " + expectedCount
+ " founded " + result.size() + ".");
}
}
if (result == null || result.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(result);
}
/**
* Extract child elements by tag name.
* @param parentElement the parent element
* @param elementName the element name
* @return the list
*/
public static List<Element> extractChildElementsByTagName(
final Element parentElement, final String elementName) {
if (elementName == null || parentElement == null) {
return null;
}
final NodeList nStepsList = parentElement.getChildNodes();
if (nStepsList == null) {
return null;
}
final List<Element> result = new ArrayList<>();
for (int i = 0; i < nStepsList.getLength(); i++) {
final Node node = nStepsList.item(i);
// Check element found
if (node == null)
continue;
if (node.getNodeType() == Node.ELEMENT_NODE) {
final Element e = (Element) node;
if (e.getTagName().equals(elementName)) {
result.add(e);
}
}
}
if (result == null || result.isEmpty()) {
return Collections.emptyList();
}
return Collections.unmodifiableList(result);
}
/**
* Extract all output parameters define in document.
* @param doc document represented tool xml
* @param stepParameters parameters for analysis
* @return all output parameters
* @throws EoulsanException if none output parameter found
*/
public static Map<String, ToolElement> extractOutputs(final Document doc,
final Map<String, Parameter> stepParameters) throws EoulsanException {
final Map<String, ToolElement> results = new HashMap<>();
final Element outputElement =
extractElementsByTagName(doc, OUTPUTS_TAG, 1).get(0);
results
.putAll(extractParamElement(outputElement, DATA_TAG, stepParameters));
results
.putAll(extractConditionalParamElement(outputElement, stepParameters));
return results;
}
/**
* Extract all input parameters define in document.
* @param doc document represented tool xml
* @param stepParameters parameters for analysis
* @return all input parameters
* @throws EoulsanException if none input parameter found
*/
public static Map<String, ToolElement> extractInputs(final Document doc,
final Map<String, Parameter> stepParameters) throws EoulsanException {
final Map<String, ToolElement> results = new HashMap<>();
final Element inputElement =
extractElementsByTagName(doc, INPUTS_TAG, 1).get(0);
results
.putAll(extractParamElement(inputElement, PARAM_TAG, stepParameters));
results
.putAll(extractConditionalParamElement(inputElement, stepParameters));
// Extract input
return results;
}
/**
* Extract command tag in string.
* @param doc document represented tool xml
* @return command string
*/
public static String extractCommand(final Document doc) {
return extractValueFromElement(doc, COMMAND_TAG, 0, null);
}
/**
* Extract interpreter attribute in string.
* @param doc document represented tool xml
* @return interpreter name
*/
public static String extractInterpreter(final Document doc) {
return extractValueFromElement(doc, COMMAND_TAG, 0, INTERPRETER_TAG);
}
/**
* Extract docker image attribute in string.
* @param doc document represented tool xml
* @return the docker image name
*/
public static String extractDockerImage(final Document doc) {
return extractValueFromElement(doc, COMMAND_TAG, 0, DOCKER_IMAGE_TAG);
}
/**
* Extract description tag in string.
* @param doc document represented tool xml
* @return description
*/
public static String extractDescription(final Document doc) {
return extractValueFromElement(doc, DESCRIPTION_TAG, 0, null);
}
/**
* Extract tool version attribute in string.
* @param doc document represented tool xml
* @return tool version string
*/
public static String extractToolVersion(final Document doc) {
return extractValueFromElement(doc, TOOL_TAG, 0, VERSION_TAG);
}
/**
* Extract tool name tag in string.
* @param doc document represented tool xml
* @return tool name string
*/
public static String extractToolName(final Document doc) {
return extractValueFromElement(doc, TOOL_TAG, 0, NAME_TAG);
}
/**
* Extract tool id tag in string.
* @param doc document represented tool xml
* @return tool id string
*/
public static String extractToolID(final Document doc) {
return extractValueFromElement(doc, TOOL_TAG, 0, ID_TAG);
}
/**
* Extract text from DOM from tag name, at the index place. If attribute name
* defined return value attribute, otherwise return content text of element.
* @param doc document represented tool xml
* @param elementName element name to extract
* @param index index of element name to extract
* @param attributeName attribute name from element name to extract
* @return value corresponding to element name content or attribute of element
* name. Return null, if none corresponding element or attribute
* found.
*/
public static String extractValueFromElement(final Document doc,
final String elementName, final int index, final String attributeName) {
// List element
final List<Element> e = XMLUtils.getElementsByTagName(doc, elementName);
if (e.isEmpty()) {
return null;
}
// Check size
if (index >= e.size()) {
return null;
}
// Return content text
if (attributeName == null) {
return e.get(index).getTextContent();
}
// Return value of attribute
return e.get(index).getAttribute(attributeName);
}
}