teichmann@5861: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
teichmann@5861: * Software engineering by Intevation GmbH
teichmann@5861: *
teichmann@5993: * This file is Free Software under the GNU AGPL (>=v3)
teichmann@5861: * and comes with ABSOLUTELY NO WARRANTY! Check out the
teichmann@5993: * documentation coming with Dive4Elements River for details.
teichmann@5861: */
teichmann@5861:
teichmann@5835: package org.dive4elements.river.client.server;
ingo@16:
ingo@16: import java.util.ArrayList;
ingo@16: import java.util.List;
ingo@16:
ingo@16: import javax.xml.xpath.XPathConstants;
ingo@16:
ingo@1367: import org.apache.log4j.Logger;
teichmann@5835: import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
teichmann@5835: import org.dive4elements.artifacts.common.utils.ClientProtocolUtils;
teichmann@5835: import org.dive4elements.artifacts.common.utils.XMLUtils;
teichmann@5835: import org.dive4elements.river.client.shared.model.ArtifactDescription;
teichmann@5835: import org.dive4elements.river.client.shared.model.DataItem;
teichmann@5835: import org.dive4elements.river.client.shared.model.DataList;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultArtifactDescription;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultData;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultDataItem;
teichmann@5835: import org.dive4elements.river.client.shared.model.DefaultOutputMode;
teichmann@5835: import org.dive4elements.river.client.shared.model.DoubleArrayData;
teichmann@5835: import org.dive4elements.river.client.shared.model.DoubleRangeData;
teichmann@5835: import org.dive4elements.river.client.shared.model.IntegerArrayData;
gernotbelger@9390: import org.dive4elements.river.client.shared.model.IntegerOptionsData;
teichmann@5835: import org.dive4elements.river.client.shared.model.IntegerRangeData;
teichmann@5835: import org.dive4elements.river.client.shared.model.LongRangeData;
teichmann@5835: import org.dive4elements.river.client.shared.model.OutputMode;
teichmann@5835: import org.dive4elements.river.client.shared.model.Recommendation;
teichmann@5835: import org.dive4elements.river.client.shared.model.WQDataItem;
gernotbelger@9390: import org.w3c.dom.Document;
gernotbelger@9390: import org.w3c.dom.Element;
gernotbelger@9390: import org.w3c.dom.Node;
gernotbelger@9390: import org.w3c.dom.NodeList;
ingo@16:
ingo@16: /**
ingo@16: * This factory class helps creating an {@link ArtifactDescription} based on the
ingo@16: * DESCRIBE document of an artifact returned by the artifact server. Use the
ingo@16: * {@link createArtifactDescription(org.w3c.dom.Document)} method with the
ingo@16: * DESCRIBE document to create such an {@link ArtifactDescription}.
ingo@16: *
ingo@16: * @author Ingo Weinzierl
ingo@16: */
ingo@16: public class ArtifactDescriptionFactory {
ingo@16:
gernotbelger@9390: private static final Logger log = Logger.getLogger(ArtifactDescriptionFactory.class);
ingo@1367:
ingo@16: public static final String XPATH_STATE_NAME = "@art:name";
ingo@16:
ingo@22: public static final String XPATH_UIPROVIDER = "@art:uiprovider";
ingo@22:
ingo@2500: public static final String XPATH_HELP_TEXT = "@art:helpText";
ingo@2500:
ingo@32: public static final String XPATH_REACHABLE_STATE = "art:state";
ingo@32:
ingo@51: public static final String XPATH_STATIC_STATE_NODE = "art:state";
ingo@51:
ingo@34: public static final String XPATH_STATIC_DATA_NODE = "art:data";
ingo@34:
ingo@34: public static final String XPATH_STATIC_ITEM_NODE = "art:item";
ingo@34:
gernotbelger@9390: public static final String XPATH_RECOMMENDED_ARTIFACTS = "/art:result/art:recommended-artifacts//*[@factory]";
ingo@803:
ingo@16: /**
ingo@16: * This method creates the {@link ArtifactDescription} of the DESCRIBE
ingo@16: * document doc.
ingo@16: *
gernotbelger@9390: * @param doc
gernotbelger@9390: * A DESCRIBE document.
ingo@16: *
ingo@16: * @return the {@link ArtifactDescription}.
ingo@16: */
gernotbelger@9390: public static ArtifactDescription createArtifactDescription(final Document doc) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.createArtifactDescription");
ingo@16:
gernotbelger@9390: final Node currentState = ClientProtocolUtils.getCurrentState(doc);
gernotbelger@9390: final Node staticNode = ClientProtocolUtils.getStaticUI(doc);
gernotbelger@9390: final Node dynamicNode = ClientProtocolUtils.getDynamicUI(doc);
gernotbelger@9390: final Node reachable = ClientProtocolUtils.getReachableStates(doc);
gernotbelger@9390: final NodeList outputs = ClientProtocolUtils.getOutputModes(doc);
ingo@16:
gernotbelger@9390: final String state = (String) XMLUtils.xpath(currentState, XPATH_STATE_NAME, XPathConstants.STRING, ArtifactNamespaceContext.INSTANCE);
ingo@1367:
teichmann@8203: log.debug("Current state name: " + state);
ingo@16:
gernotbelger@9390: final DataList currentData = extractCurrentData(dynamicNode, state);
gernotbelger@9390: final DataList[] old = extractOldData(staticNode);
gernotbelger@9390: final String[] states = extractReachableStates(reachable);
gernotbelger@9390: final OutputMode[] outs = extractOutputModes(outputs);
gernotbelger@9390: final Recommendation[] rec = extractRecommendedArtifacts(doc);
ingo@16:
gernotbelger@9390: return new DefaultArtifactDescription(old, currentData, state, states, outs, rec);
ingo@16: }
ingo@16:
ingo@16: /**
ingo@16: * This method extracts the data that the user is able to enter in the
ingo@16: * current state of the artifact.
ingo@16: *
gernotbelger@9390: * @param dynamicNode
gernotbelger@9390: * The dynamic node of the DESCRIBE document.
gernotbelger@9390: * @param state
gernotbelger@9390: * The name of the current state.
ingo@16: *
ingo@16: * @return A {@link Data} object that represents the data which might be
gernotbelger@9390: * entered by the user in the current state or null, if no data might be
gernotbelger@9390: * entered.
ingo@16: */
gernotbelger@9390: protected static DataList extractCurrentData(final Node dynamicNode, final String state) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractCurrentData");
ingo@16:
gernotbelger@9390: final NodeList data = ClientProtocolUtils.getSelectNode(dynamicNode);
gernotbelger@9390: final String help = extractHelpText(dynamicNode);
gernotbelger@9390: final String uiProvider = extractUIProvider(dynamicNode);
ingo@16:
ingo@51: if (data == null || data.getLength() == 0) {
ingo@51: return null;
ingo@51: }
ingo@16:
gernotbelger@9390: final int dataNum = data.getLength();
gernotbelger@9390: final DataList list = new DataList(state, dataNum, uiProvider, null, help);
ingo@51:
ingo@51: for (int i = 0; i < dataNum; i++) {
gernotbelger@9390: final Element d = (Element) data.item(i);
gernotbelger@9390: final String label = ClientProtocolUtils.getLabel(d);
gernotbelger@9390: final String name = XMLUtils.xpathString(d, "@art:name", ArtifactNamespaceContext.INSTANCE);
gernotbelger@9390: final String type = XMLUtils.xpathString(d, "@art:type", ArtifactNamespaceContext.INSTANCE);
ingo@51:
teichmann@8203: log.debug("Create new IntegerRangeData object for: " + name);
teichmann@8203: log.debug("New Data is from type: " + type);
ingo@51:
felix@1592: // TODO replace with DataFactory.
felix@1592:
ingo@1522: if (type == null || type.length() == 0) {
gernotbelger@9390: final NodeList choices = ClientProtocolUtils.getItemNodes(d);
gernotbelger@9390: final DataItem[] dataItems = extractCurrentDataItems(choices);
gernotbelger@9390: final DataItem def = extractDefaultDataItem(d);
ingo@51:
ingo@1522: list.add(new DefaultData(name, label, null, dataItems, def));
gernotbelger@9390: } else if (type.equals("intrange")) {
gernotbelger@9390: final String min = ClientProtocolUtils.getMinNode(d);
gernotbelger@9390: final String max = ClientProtocolUtils.getMaxNode(d);
ingo@1566:
gernotbelger@9390: final String defMin = ClientProtocolUtils.getDefMin(d);
gernotbelger@9390: final String defMax = ClientProtocolUtils.getDefMax(d);
ingo@1522:
ingo@1522: try {
gernotbelger@9390: final int lower = Integer.parseInt(min);
gernotbelger@9390: final int upper = Integer.parseInt(max);
ingo@4132:
ingo@4132: if (defMin != null && defMax != null) {
gernotbelger@9390: list.add(new IntegerRangeData(name, label, lower, upper, Integer.parseInt(defMin), Integer.parseInt(defMax)));
gernotbelger@9390: } else {
gernotbelger@9390: list.add(new IntegerRangeData(name, label, lower, upper));
ingo@4132: }
ingo@4132: }
gernotbelger@9390: catch (final NumberFormatException nfe) {
teichmann@8203: log.warn("NumberFormatException: ", nfe);
ingo@4132: }
gernotbelger@9390: } else if (type.equals("longrange")) {
gernotbelger@9390: final String min = ClientProtocolUtils.getMinNode(d);
gernotbelger@9390: final String max = ClientProtocolUtils.getMaxNode(d);
gernotbelger@9390:
gernotbelger@9390: final String defMin = ClientProtocolUtils.getDefMin(d);
gernotbelger@9390: final String defMax = ClientProtocolUtils.getDefMax(d);
gernotbelger@9390:
gernotbelger@9390: try {
gernotbelger@9390: final long lower = Long.valueOf(min);
gernotbelger@9390: final long upper = Long.valueOf(max);
gernotbelger@9390:
gernotbelger@9390: if (defMin != null && defMax != null) {
gernotbelger@9390: list.add(new LongRangeData(name, label, lower, upper, Long.valueOf(defMin), Long.valueOf(defMax)));
gernotbelger@9390: }
gernotbelger@9390: }
gernotbelger@9390: catch (final NumberFormatException nfe) {
gernotbelger@9390: log.warn("NumberFormatException: ", nfe);
gernotbelger@9390: }
gernotbelger@9390: } else if (type.equals("intarray")) {
ingo@1527: list.add(new IntegerArrayData(name, label, null));
gernotbelger@9390: } else if (type.equals("intoptions") && uiProvider.startsWith("parameter-matrix")// uiProvider.equals("parameter-matrix") // what the...? used to be
gernotbelger@9390: // "equals", but column-name for "itemname" refactoring created new
gernotbelger@9390: // UIProviderFactory-Names starting with "parameter-matrix"
tom@8856: ) {
ingo@2532: list.add(DataFactory.createIntegerOptionsData(d, name, label));
gernotbelger@9390: } else if (type.equals("options")) {
ingo@2532: list.add(DataFactory.createStringOptionsData(d, name, label));
gernotbelger@9390: } else if (type.equals("intoptions")) {
gernotbelger@9390: final NodeList choices = ClientProtocolUtils.getItemNodes(d);
gernotbelger@9390: final DataItem[] opts = extractCurrentDataItems(choices);
ingo@1527:
ingo@1527: list.add(new IntegerOptionsData(name, label, opts));
gernotbelger@9390: } else if (type.equals("doublearray")) {
ingo@1595: list.add(new DoubleArrayData(name, label, null));
gernotbelger@9390: } else if (type.equals("multiattribute")) {
rrenkert@7825: list.add(DataFactory.createMultiAttributeData(d, name, label));
gernotbelger@9390: } else {
teichmann@8203: log.warn("Unrecognized Dynamic data type.");
gernotbelger@9390: final NodeList choices = ClientProtocolUtils.getItemNodes(d);
gernotbelger@9390: final DataItem[] dataItems = extractCurrentDataItems(choices);
gernotbelger@9390: final DataItem def = extractDefaultDataItem(d);
felix@1592:
gernotbelger@9390: final String min = ClientProtocolUtils.getMinNode(d);
gernotbelger@9390: final String max = ClientProtocolUtils.getMaxNode(d);
felix@1593: if (min != null && max != null) {
gernotbelger@9390: list.add(new DoubleRangeData(name, label, Double.valueOf(min), Double.valueOf(max), Double.valueOf(min), Double.valueOf(max)));
felix@1593: }
felix@1593:
felix@1592: list.add(new DefaultData(name, label, null, dataItems, def));
felix@1592: }
felix@1592:
ingo@51: }
ingo@51:
ingo@51: return list;
ingo@16: }
ingo@16:
ingo@16: /**
ingo@515: * This method extracts the default value of a Data object.
ingo@515: *
gernotbelger@9390: * @param data
gernotbelger@9390: * The data object node.
ingo@515: *
ingo@515: * @return the default DataItem.
ingo@515: */
gernotbelger@9390: protected static DataItem extractDefaultDataItem(final Node data) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractDefaultDataItem");
ingo@515:
gernotbelger@9390: final String value = XMLUtils.xpathString(data, "@art:defaultValue", ArtifactNamespaceContext.INSTANCE);
ingo@515:
gernotbelger@9390: final String label = XMLUtils.xpathString(data, "@art:defaultLabel", ArtifactNamespaceContext.INSTANCE);
ingo@515:
ingo@515: if (value != null && label != null) {
ingo@515: return new DefaultDataItem(label, null, value);
ingo@515: }
ingo@515:
ingo@515: return null;
ingo@515: }
ingo@515:
ingo@515: /**
ingo@16: * This method extract the {@link DataItem}s of the DESCRIBE document.
ingo@16: *
gernotbelger@9390: * @param items
gernotbelger@9390: * The items in the DESCRIBE document.
ingo@16: *
ingo@16: * @return the {@link DataItem}s.
ingo@16: */
gernotbelger@9390: protected static DataItem[] extractCurrentDataItems(final NodeList items) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractCurrentDataItems");
ingo@16:
ingo@16: if (items == null || items.getLength() == 0) {
teichmann@8203: log.debug("No data items found.");
ingo@16: return null;
ingo@16: }
ingo@16:
gernotbelger@9390: final int count = items.getLength();
ingo@16:
gernotbelger@9390: final List dataItems = new ArrayList(count);
ingo@16:
ingo@16: for (int i = 0; i < count; i++) {
gernotbelger@9390: final Node item = items.item(i);
gernotbelger@9390: final String label = ClientProtocolUtils.getLabel(item);
gernotbelger@9390: final String value = ClientProtocolUtils.getValue(item);
ingo@16:
gernotbelger@9390: final double[] mmQ = extractMinMaxQValues(item);
gernotbelger@9390: final double[] mmW = extractMinMaxWValues(item);
ingo@565:
ingo@565: if (mmQ != null || mmW != null) {
ingo@565: dataItems.add(new WQDataItem(label, null, value, mmQ, mmW));
gernotbelger@9390: } else {
ingo@565: dataItems.add(new DefaultDataItem(label, null, value));
ingo@565: }
ingo@16: }
ingo@16:
sascha@3379: return dataItems.toArray(new DataItem[count]);
ingo@16: }
ingo@22:
gernotbelger@9390: protected static double[] extractMinMaxQValues(final Node item) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractMinMaxQValues");
ingo@565:
ingo@565: if (item == null) {
teichmann@8203: log.debug("This node is empty - no min/max Q values.");
ingo@565: return null;
ingo@565: }
ingo@565:
gernotbelger@9390: final Node node = (Node) XMLUtils.xpath(item, "art:range[@art:type='Q']", XPathConstants.NODE, ArtifactNamespaceContext.INSTANCE);
ingo@565:
ingo@565: if (node == null) {
teichmann@8203: log.debug("No min/max Q values found.");
ingo@565: return null;
ingo@565: }
ingo@565:
ingo@565: return extractMinMaxValues(node);
ingo@565: }
ingo@565:
gernotbelger@9390: protected static double[] extractMinMaxWValues(final Node item) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractMinMaxWValues");
ingo@565:
ingo@565: if (item == null) {
teichmann@8203: log.debug("This node is empty - no min/max W values.");
ingo@565: return null;
ingo@565: }
ingo@565:
gernotbelger@9390: final Node node = (Node) XMLUtils.xpath(item, "art:range[@art:type='W']", XPathConstants.NODE, ArtifactNamespaceContext.INSTANCE);
ingo@565:
ingo@565: if (node == null) {
teichmann@8203: log.debug("No min/max W values found.");
ingo@565: return null;
ingo@565: }
ingo@565:
ingo@565: return extractMinMaxValues(node);
ingo@565: }
ingo@565:
gernotbelger@9390: protected static double[] extractMinMaxValues(final Node node) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractMinMaxValues");
ingo@565:
gernotbelger@9390: final String minStr = XMLUtils.xpathString(node, "art:min/text()", ArtifactNamespaceContext.INSTANCE);
ingo@565:
gernotbelger@9390: final String maxStr = XMLUtils.xpathString(node, "art:max/text()", ArtifactNamespaceContext.INSTANCE);
ingo@565:
ingo@565: if (maxStr == null || minStr == null) {
teichmann@8203: log.debug("No min/max values found.");
ingo@565: return null;
ingo@565: }
ingo@565:
ingo@565: try {
gernotbelger@9390: final double min = Double.valueOf(minStr);
gernotbelger@9390: final double max = Double.valueOf(maxStr);
ingo@565:
ingo@565: return new double[] { min, max };
ingo@565: }
gernotbelger@9390: catch (final NumberFormatException nfe) {
teichmann@8203: log.debug("Error while parsing min/max values.");
ingo@565: }
ingo@565:
ingo@565: return null;
ingo@565: }
ingo@565:
ingo@22: /**
ingo@34: * This method extracts the data objects from the data node of the static ui
ingo@34: * part of the DESCRIBE document.
ingo@34: *
gernotbelger@9390: * @param staticNode
gernotbelger@9390: * The static ui node of the DESCRIBE.
ingo@34: *
ingo@51: * @return the DataList objects.
ingo@34: */
gernotbelger@9390: protected static DataList[] extractOldData(final Node staticNode) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractOldData()");
ingo@34:
gernotbelger@9390: final NodeList stateNodes = (NodeList) XMLUtils.xpath(staticNode, XPATH_STATIC_STATE_NODE, XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);
ingo@34:
ingo@51: if (stateNodes == null || stateNodes.getLength() == 0) {
teichmann@8203: log.debug("No old items found.");
ingo@34: return null;
ingo@34: }
ingo@34:
gernotbelger@9390: final int count = stateNodes.getLength();
gernotbelger@9390: final DataList[] data = new DataList[count];
ingo@34:
ingo@34: for (int i = 0; i < count; i++) {
gernotbelger@9390: final Node tmp = stateNodes.item(i);
ingo@34:
gernotbelger@9390: final String name = XMLUtils.xpathString(tmp, "@art:name", ArtifactNamespaceContext.INSTANCE);
gernotbelger@9390: final String uiprovider = XMLUtils.xpathString(tmp, "@art:uiprovider", ArtifactNamespaceContext.INSTANCE);
gernotbelger@9390: final String label = XMLUtils.xpathString(tmp, "@art:label", ArtifactNamespaceContext.INSTANCE);
gernotbelger@9390: final String help = XMLUtils.xpathString(tmp, "@art:helpText", ArtifactNamespaceContext.INSTANCE);
ingo@34:
gernotbelger@9390: final NodeList dataNodes = (NodeList) XMLUtils.xpath(tmp, XPATH_STATIC_DATA_NODE, XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);
ingo@34:
ingo@51: if (dataNodes == null || dataNodes.getLength() == 0) {
ingo@51: continue;
ingo@51: }
ingo@51:
gernotbelger@9390: final int size = dataNodes.getLength();
gernotbelger@9390: final DataList list = new DataList(name, size, uiprovider, label, help);
ingo@51:
ingo@51: for (int j = 0; j < size; j++) {
gernotbelger@9390: final Node dataNode = dataNodes.item(j);
ingo@51:
ingo@1571: list.add(DataFactory.createDataFromElement((Element) dataNode));
ingo@51:
ingo@51: data[i] = list;
ingo@51: }
ingo@34: }
ingo@34:
ingo@34: return data;
ingo@34: }
ingo@34:
ingo@34: /**
ingo@22: * This method extracts the UIProvider specified by the data node.
ingo@22: *
gernotbelger@9390: * @param data
gernotbelger@9390: * The data node.
ingo@22: *
ingo@22: * @return the UIProvider that is specified in the data node.
ingo@22: */
gernotbelger@9390: protected static String extractUIProvider(final Node ui) {
gernotbelger@9390: return (String) XMLUtils.xpath(ui, XPATH_UIPROVIDER, XPathConstants.STRING, ArtifactNamespaceContext.INSTANCE);
ingo@22: }
ingo@32:
ingo@32: /**
ingo@2500: * This method extracts the help text specified by the data node.
ingo@2500: *
gernotbelger@9390: * @param ui
gernotbelger@9390: * The data node.
ingo@2500: *
ingo@2500: * @return the help text.
ingo@2500: */
gernotbelger@9390: protected static String extractHelpText(final Node ui) {
gernotbelger@9390: return (String) XMLUtils.xpath(ui, XPATH_HELP_TEXT, XPathConstants.STRING, ArtifactNamespaceContext.INSTANCE);
ingo@2500: }
ingo@2500:
ingo@2500: /**
ingo@32: * This method extracts the reachable states of the current artifact.
ingo@32: *
gernotbelger@9390: * @param reachable
gernotbelger@9390: * The reachable states node.
ingo@32: *
ingo@32: * @return an array with identifiers of reachable states.
ingo@32: */
gernotbelger@9390: protected static String[] extractReachableStates(final Node reachable) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractReachableStates()");
ingo@32:
gernotbelger@9390: final NodeList list = (NodeList) XMLUtils.xpath(reachable, XPATH_REACHABLE_STATE, XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);
ingo@32:
ingo@32: if (list == null || list.getLength() == 0) {
ingo@32: return null;
ingo@32: }
ingo@32:
gernotbelger@9390: final int count = list.getLength();
ingo@32:
gernotbelger@9390: final String[] states = new String[count];
ingo@32:
ingo@32: for (int i = 0; i < count; i++) {
gernotbelger@9390: final Node state = list.item(i);
ingo@32:
gernotbelger@9390: final String name = XMLUtils.xpathString(state, "@art:name", ArtifactNamespaceContext.INSTANCE);
ingo@32:
ingo@32: states[i] = name;
ingo@32: }
ingo@32:
ingo@32: return states;
ingo@32: }
ingo@65:
ingo@65: /**
ingo@65: * This method extract available output modes of the the current artifact.
ingo@65: *
gernotbelger@9390: * @param outputs
gernotbelger@9390: * A list of nodes that contain information about output
gernotbelger@9390: * modes.
ingo@65: *
ingo@65: * @return an array of Output modes.
ingo@65: */
gernotbelger@9390: protected static OutputMode[] extractOutputModes(final NodeList outputs) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractOutputModes");
ingo@65:
ingo@65: if (outputs == null || outputs.getLength() == 0) {
ingo@65: return null;
ingo@65: }
ingo@65:
gernotbelger@9390: final int size = outputs.getLength();
ingo@65:
gernotbelger@9390: final List outs = new ArrayList(size);
ingo@65:
ingo@65: for (int i = 0; i < size; i++) {
gernotbelger@9390: final Node out = outputs.item(i);
ingo@65:
gernotbelger@9390: final String name = XMLUtils.xpathString(out, "@art:name", ArtifactNamespaceContext.INSTANCE);
gernotbelger@9390: final String desc = XMLUtils.xpathString(out, "@art:description", ArtifactNamespaceContext.INSTANCE);
gernotbelger@9390: final String mimeType = XMLUtils.xpathString(out, "@art:mime-type", ArtifactNamespaceContext.INSTANCE);
ingo@65:
ingo@65: if (name != null) {
ingo@65: outs.add(new DefaultOutputMode(name, desc, mimeType));
gernotbelger@9390: } else {
teichmann@8203: log.debug("Found an invalid output mode.");
ingo@65: }
ingo@65: }
ingo@65:
gernotbelger@9390: return outs.toArray(new OutputMode[size]);
ingo@65: }
ingo@803:
gernotbelger@9390: protected static Recommendation[] extractRecommendedArtifacts(final Document doc) {
teichmann@8203: log.debug("ArtifactDescriptionFactory.extractRecommendedArtifacts.");
ingo@803:
gernotbelger@9390: final NodeList list = (NodeList) XMLUtils.xpath(doc, XPATH_RECOMMENDED_ARTIFACTS, XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);
ingo@803:
gernotbelger@9390: final int num = list != null ? list.getLength() : 0;
ingo@803:
gernotbelger@9390: final Recommendation[] rec = new Recommendation[num];
ingo@803:
ingo@803: for (int i = 0; i < num; i++) {
gernotbelger@9390: final Element e = (Element) list.item(i);
gernotbelger@9390: final String factory = e.getAttribute("factory");
gernotbelger@9390: final String index = e.getAttribute("ids");
gernotbelger@9390: final String targetOut = e.getAttribute("target_out");
ingo@803:
ingo@807: if (factory != null && factory.length() > 0) {
gernotbelger@9390: log.debug("Adding Recommendation. Factory: " + factory + " IDs: " + index + " target out " + targetOut);
gernotbelger@9390: rec[i] = new Recommendation(factory, index, null, null, targetOut);
ingo@803: }
ingo@803: }
ingo@803:
ingo@807: return rec;
ingo@803: }
ingo@16: }
ingo@16: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :