/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.components.cpacs.vampzeroinitializer.gui;
import static javax.xml.xpath.XPathConstants.NODESET;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import de.rcenvironment.components.cpacs.vampzeroinitializer.gui.model.Component;
import de.rcenvironment.components.cpacs.vampzeroinitializer.gui.model.Discipline;
import de.rcenvironment.components.cpacs.vampzeroinitializer.gui.model.Parameter;
import de.rcenvironment.core.utils.common.xml.XMLException;
import de.rcenvironment.core.utils.common.xml.api.XMLSupportService;
import de.rcenvironment.core.utils.incubator.ServiceRegistry;
/**
* Parse the XML that describes the GUI and the parameters.
*
* @author Arne Bachmann
* @author Markus Kunde
* @author Brigitte Boden
*/
public final class GuiInputParser {
private static final String NAME = "name";
/**
* The xpath object.
*/
private XPath xpath;
/**
* The XMLSupport service.
*/
private XMLSupportService xmlSupport;
/**
* Constructor.
*/
public GuiInputParser() {
xpath = XPathFactory.newInstance().newXPath();
xmlSupport = ServiceRegistry.createAccessFor(this).getService(XMLSupportService.class);
}
/**
* Parse the given file and return the model objects.
*
* @param configuration The file to read
* @return The components
* @throws XPathExpressionException For any parsing error
* @throws XMLException Error in XML handling
*/
public List<Component> parse(final String configuration) throws XPathExpressionException, XMLException {
final Document doc;
if (configuration == null) {
return new ArrayList<Component>();
}
doc = xmlSupport.readXMLFromString(configuration);
return parse(doc, "/cpacs/toolspecific/vampZero/components/component");
}
/**
* Parse the input document in vampzero format.
*
* @param stream The file to read
* @return The components
* @throws XPathExpressionException For any parsing error
* @throws XMLException Error in XML handling
*/
public List<Component> parse(final InputStream stream) throws XPathExpressionException, XMLException {
final Document doc;
if (stream == null) {
return new ArrayList<Component>();
}
doc = xmlSupport.readXMLFromStream(stream);
return parse(doc, "/zeroGuiIn/component");
}
/**
* Parse the input document in Cpacs or vampzero format (depending on prefix).
*
* @param doc
* @param xpathPrefix
* @return a component list
* @throws XPathExpressionException
*/
protected List<Component> parse(final Document doc, final String xpathPrefix) throws XPathExpressionException {
final List<Component> componentList = new ArrayList<Component>();
final List<Discipline> disciplineList = new ArrayList<Discipline>();
final List<Parameter> parameterList = new ArrayList<Parameter>();
final NodeList components = (NodeList) xpath.evaluate(xpathPrefix, doc.getDocumentElement(), NODESET);
int cn = components.getLength();
for (int c = 0; c < cn; c++) {
final Node component = components.item(c);
final String componentName = getNodeTextValue(component, NAME);
final NodeList disciplines = (NodeList) xpath.evaluate("disciplines/discipline", component, NODESET);
disciplineList.clear();
int dn = disciplines.getLength();
for (int d = 0; d < dn; d++) {
final Node discipline = disciplines.item(d);
final String disciplineName = getNodeTextValue(discipline, NAME);
final NodeList parameters = (NodeList) xpath.evaluate("parameters/parameter", discipline, NODESET);
parameterList.clear();
int pn = parameters.getLength();
for (int p = 0; p < pn; p++) {
final Node parameter = parameters.item(p);
final String parameterName = getNodeTextValue(parameter, NAME);
final String parameterDescription = getNodeTextValue(parameter, "description");
final String parameterValue = getNodeTextValue(parameter, "value");
final String parameterFactor = getNodeTextValue(parameter, "factor");
final Parameter newParameter = ((Parameter) new Parameter().setName(parameterName))
.setDescription(parameterDescription)
.setValue(parameterValue)
.setFactor(parameterFactor);
parameterList.add(newParameter);
}
Collections.sort(parameterList);
final Discipline newDiscipline = ((Discipline) new Discipline().setName(disciplineName)).setParameters(parameterList);
disciplineList.add(newDiscipline);
}
Collections.sort(disciplineList);
final Component newComponent = ((Component) new Component().setName(componentName)).setDisciplines(disciplineList);
componentList.add(newComponent);
}
Collections.sort(componentList);
return componentList;
}
/**
* Small XML helper.
*
* @param node The node
* @return The text value
* @throws XPathExpressionException
*/
private static String getNodeTextValue(final Node parentNode, final String elementName) throws XPathExpressionException {
final NodeList nodes = parentNode.getChildNodes();
int n = nodes.getLength();
for (int i = 0; i < n; i++) {
final Node node = nodes.item(i);
if (node.getNodeName().equals(elementName)) {
return node.getTextContent().trim();
}
}
return null;
}
}