ingo@16: package de.intevation.flys.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@16: import org.w3c.dom.Document; ingo@16: import org.w3c.dom.Node; ingo@16: import org.w3c.dom.NodeList; ingo@16: ingo@16: import de.intevation.artifacts.common.ArtifactNamespaceContext; ingo@16: import de.intevation.artifacts.common.utils.ClientProtocolUtils; ingo@16: import de.intevation.artifacts.common.utils.XMLUtils; ingo@16: ingo@16: import de.intevation.flys.client.shared.model.ArtifactDescription; ingo@16: import de.intevation.flys.client.shared.model.DataItem; ingo@51: import de.intevation.flys.client.shared.model.DataList; ingo@51: import de.intevation.flys.client.shared.model.DefaultArtifactDescription; ingo@16: import de.intevation.flys.client.shared.model.DefaultData; ingo@16: import de.intevation.flys.client.shared.model.DefaultDataItem; ingo@65: import de.intevation.flys.client.shared.model.DefaultOutputMode; ingo@65: import de.intevation.flys.client.shared.model.OutputMode; ingo@16: 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: 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@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: ingo@16: /** ingo@16: * This method creates the {@link ArtifactDescription} of the DESCRIBE ingo@16: * document doc. ingo@16: * ingo@16: * @param doc A DESCRIBE document. ingo@16: * ingo@16: * @return the {@link ArtifactDescription}. ingo@16: */ ingo@16: public static ArtifactDescription createArtifactDescription(Document doc) { ingo@16: System.out.println("ArtifactDescriptionFactory - create()"); ingo@16: ingo@16: Node currentState = ClientProtocolUtils.getCurrentState(doc); ingo@16: Node staticNode = ClientProtocolUtils.getStaticUI(doc); ingo@16: Node dynamicNode = ClientProtocolUtils.getDynamicUI(doc); ingo@32: Node reachable = ClientProtocolUtils.getReachableStates(doc); ingo@65: NodeList outputs = ClientProtocolUtils.getOutputModes(doc); ingo@16: ingo@16: String state = (String) XMLUtils.xpath( ingo@16: currentState, ingo@16: XPATH_STATE_NAME, ingo@16: XPathConstants.STRING, ingo@16: ArtifactNamespaceContext.INSTANCE); ingo@16: System.out.println("Current state name: " + state); ingo@16: ingo@51: DataList currentData = extractCurrentData(dynamicNode, state); ingo@51: DataList[] old = extractOldData(staticNode); ingo@34: String[] states = extractReachableStates(reachable); ingo@65: OutputMode[] outs = extractOutputModes(outputs); ingo@16: ingo@65: return new DefaultArtifactDescription( ingo@65: old, ingo@65: currentData, ingo@65: state, ingo@65: states, ingo@65: outs); ingo@16: } 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: * ingo@16: * @param dynamicNode The dynamic node of the DESCRIBE document. ingo@51: * @param state The name of the current state. ingo@16: * ingo@16: * @return A {@link Data} object that represents the data which might be ingo@16: * entered by the user in the current state or null, if no data might be ingo@16: * entered. ingo@16: */ ingo@51: protected static DataList extractCurrentData(Node dynamicNode, String state) { ingo@16: System.out.println("ArtifactDescriptionFactory - extractCurrentData()"); ingo@16: ingo@51: NodeList data = ClientProtocolUtils.getSelectNode(dynamicNode); ingo@51: String uiProvider = extractUIProvider(dynamicNode); ingo@16: ingo@51: if (data == null || data.getLength() == 0) { ingo@51: return null; ingo@51: } ingo@16: ingo@51: int dataNum = data.getLength(); ingo@51: DataList list = new DataList(state, dataNum, uiProvider); ingo@51: ingo@51: for (int i = 0; i < dataNum; i++) { ingo@51: Node d = data.item(i); ingo@51: ingo@51: NodeList choices = ClientProtocolUtils.getItemNodes(d); ingo@51: String label = ClientProtocolUtils.getLabel(d); ingo@51: String name = XMLUtils.xpathString( ingo@51: d, "@art:name", ArtifactNamespaceContext.INSTANCE); ingo@51: ingo@51: DataItem[] dataItems = extractCurrentDataItems(choices); ingo@515: DataItem def = extractDefaultDataItem(d); ingo@51: ingo@515: list.add(new DefaultData(name, label, null, dataItems, def)); ingo@51: } ingo@51: ingo@51: return list; ingo@16: } ingo@16: ingo@16: ingo@16: /** ingo@515: * This method extracts the default value of a Data object. ingo@515: * ingo@515: * @param data The data object node. ingo@515: * ingo@515: * @return the default DataItem. ingo@515: */ ingo@515: protected static DataItem extractDefaultDataItem(Node data) { ingo@515: System.out.println( ingo@515: "ArtifactDescriptionFactory - extractSelectedDataItem"); ingo@515: ingo@515: String value = XMLUtils.xpathString( ingo@515: data, "@art:defaultValue", ArtifactNamespaceContext.INSTANCE); ingo@515: ingo@515: String label = XMLUtils.xpathString( ingo@515: 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@515: /** ingo@16: * This method extract the {@link DataItem}s of the DESCRIBE document. ingo@16: * ingo@16: * @param items The items in the DESCRIBE document. ingo@16: * ingo@16: * @return the {@link DataItem}s. ingo@16: */ ingo@16: protected static DataItem[] extractCurrentDataItems(NodeList items) { ingo@16: System.out.println( ingo@16: "ArtifactDescriptionFactory - extractCurrentDataItems()"); ingo@16: ingo@16: if (items == null || items.getLength() == 0) { ingo@16: System.out.println("No data items found."); ingo@16: return null; ingo@16: } ingo@16: ingo@16: int count = items.getLength(); ingo@16: ingo@16: List dataItems = new ArrayList(count); ingo@16: ingo@16: for (int i = 0; i < count; i++) { ingo@16: Node item = items.item(i); ingo@16: String label = ClientProtocolUtils.getLabel(item); ingo@16: String value = ClientProtocolUtils.getValue(item); ingo@16: ingo@16: dataItems.add(new DefaultDataItem(label, null, value)); ingo@16: } ingo@16: ingo@16: return (DataItem[]) dataItems.toArray(new DataItem[count]); ingo@16: } ingo@22: ingo@22: 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: * ingo@34: * @param staticNode The static ui node of the DESCRIBE. ingo@34: * ingo@51: * @return the DataList objects. ingo@34: */ ingo@51: protected static DataList[] extractOldData(Node staticNode) { ingo@34: System.out.println("ArtifactDescriptionFactory - extractOldData()"); ingo@34: ingo@51: NodeList stateNodes = (NodeList) XMLUtils.xpath( ingo@34: staticNode, ingo@51: XPATH_STATIC_STATE_NODE, ingo@34: XPathConstants.NODESET, ingo@34: ArtifactNamespaceContext.INSTANCE); ingo@34: ingo@51: if (stateNodes == null || stateNodes.getLength() == 0) { ingo@34: System.out.println("No old items found."); ingo@34: return null; ingo@34: } ingo@34: ingo@51: int count = stateNodes.getLength(); ingo@51: DataList[] data = new DataList[count]; ingo@34: ingo@34: for (int i = 0; i < count; i++) { ingo@51: Node tmp = stateNodes.item(i); ingo@34: ingo@34: String name = XMLUtils.xpathString( ingo@34: tmp, "@art:name", ArtifactNamespaceContext.INSTANCE); ingo@52: String uiprovider = XMLUtils.xpathString( ingo@52: tmp, "@art:uiprovider", ArtifactNamespaceContext.INSTANCE); ingo@52: String label = XMLUtils.xpathString( ingo@52: tmp, "@art:label", ArtifactNamespaceContext.INSTANCE); ingo@34: ingo@51: NodeList dataNodes = (NodeList) XMLUtils.xpath( ingo@51: tmp, ingo@51: XPATH_STATIC_DATA_NODE, ingo@51: XPathConstants.NODESET, ingo@51: ArtifactNamespaceContext.INSTANCE); ingo@34: ingo@51: if (dataNodes == null || dataNodes.getLength() == 0) { ingo@51: continue; ingo@51: } ingo@51: ingo@51: int size = dataNodes.getLength(); ingo@52: DataList list = new DataList(name, size, uiprovider, label); ingo@51: ingo@51: for (int j = 0; j < size; j++) { ingo@51: Node dataNode = dataNodes.item(j); ingo@51: ingo@51: String dName = XMLUtils.xpathString( ingo@51: dataNode, "@art:name", ArtifactNamespaceContext.INSTANCE); ingo@51: String dType = XMLUtils.xpathString( ingo@51: dataNode, "@art:type", ArtifactNamespaceContext.INSTANCE); ingo@51: ingo@51: DataItem[] items = extractOldDataItems(dataNode); ingo@51: ingo@51: list.add(new DefaultData(dName, dName, dType, items)); ingo@51: ingo@51: data[i] = list; ingo@51: } ingo@34: } ingo@34: ingo@34: return data; ingo@34: } ingo@34: ingo@34: ingo@34: /** ingo@34: * This method extracts the data items from the data nodes that are placed ingo@34: * in the static ui part of the DESCRIBE document. ingo@34: * ingo@34: * @param dataNode A data node that contains items. ingo@34: * ingo@34: * @return a list of DataItems. ingo@34: */ ingo@34: protected static DataItem[] extractOldDataItems(Node dataNode) { ingo@34: NodeList itemList = (NodeList) XMLUtils.xpath( ingo@34: dataNode, ingo@34: XPATH_STATIC_ITEM_NODE, ingo@34: XPathConstants.NODESET, ingo@34: ArtifactNamespaceContext.INSTANCE); ingo@34: ingo@34: if (itemList == null || itemList.getLength() == 0) { ingo@34: System.out.println("No old data items found."); ingo@34: return null; ingo@34: } ingo@34: ingo@34: int count = itemList.getLength(); ingo@34: ingo@34: DataItem[] items = new DataItem[count]; ingo@34: ingo@34: for (int i = 0; i < count; i++) { ingo@34: Node tmp = itemList.item(i); ingo@34: ingo@34: String value = XMLUtils.xpathString( ingo@34: tmp, "@art:value", ArtifactNamespaceContext.INSTANCE); ingo@61: String label = XMLUtils.xpathString( ingo@61: tmp, "@art:label", ArtifactNamespaceContext.INSTANCE); ingo@34: ingo@61: items[i] = new DefaultDataItem(label, label, value); ingo@34: } ingo@34: ingo@34: return items; ingo@34: } ingo@34: ingo@34: ingo@34: /** ingo@22: * This method extracts the UIProvider specified by the data node. ingo@22: * ingo@22: * @param data The data node. ingo@22: * ingo@22: * @return the UIProvider that is specified in the data node. ingo@22: */ ingo@51: protected static String extractUIProvider(Node ui) { ingo@22: return (String) XMLUtils.xpath( ingo@51: ui, ingo@22: XPATH_UIPROVIDER, ingo@22: XPathConstants.STRING, ingo@22: ArtifactNamespaceContext.INSTANCE); ingo@22: } ingo@32: ingo@32: ingo@32: /** ingo@32: * This method extracts the reachable states of the current artifact. ingo@32: * ingo@32: * @param reachable The reachable states node. ingo@32: * ingo@32: * @return an array with identifiers of reachable states. ingo@32: */ ingo@32: protected static String[] extractReachableStates(Node reachable) { ingo@32: System.out.println("ArtifactDescriptionFactory - extractReachableStates()"); ingo@32: ingo@32: NodeList list = (NodeList) XMLUtils.xpath( ingo@32: reachable, ingo@32: XPATH_REACHABLE_STATE, ingo@32: XPathConstants.NODESET, ingo@32: ArtifactNamespaceContext.INSTANCE); ingo@32: ingo@32: if (list == null || list.getLength() == 0) { ingo@32: return null; ingo@32: } ingo@32: ingo@32: int count = list.getLength(); ingo@32: ingo@32: String[] states = new String[count]; ingo@32: ingo@32: for (int i = 0; i < count; i++) { ingo@32: Node state = list.item(i); ingo@32: ingo@32: String name = XMLUtils.xpathString( ingo@32: 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: /** ingo@65: * This method extract available output modes of the the current artifact. ingo@65: * ingo@65: * @param outputs A list of nodes that contain information about output ingo@65: * modes. ingo@65: * ingo@65: * @return an array of Output modes. ingo@65: */ ingo@65: protected static OutputMode[] extractOutputModes(NodeList outputs) { ingo@65: System.out.println("ArtifactDescriptionFactory - extractOutputModes()"); ingo@65: ingo@65: if (outputs == null || outputs.getLength() == 0) { ingo@65: return null; ingo@65: } ingo@65: ingo@65: int size = outputs.getLength(); ingo@65: ingo@65: List outs = new ArrayList(size); ingo@65: ingo@65: for (int i = 0; i < size; i++) { ingo@65: Node out = outputs.item(i); ingo@65: ingo@65: String name = XMLUtils.xpathString( ingo@65: out, "@art:name", ArtifactNamespaceContext.INSTANCE); ingo@65: String desc = XMLUtils.xpathString( ingo@65: out, "@art:description", ArtifactNamespaceContext.INSTANCE); ingo@65: String mimeType = XMLUtils.xpathString( ingo@65: out, "@art:mime-type", ArtifactNamespaceContext.INSTANCE); ingo@65: ingo@65: if (name != null) { ingo@65: outs.add(new DefaultOutputMode(name, desc, mimeType)); ingo@65: } ingo@65: else { ingo@65: System.err.println("Found an invalid output mode."); ingo@65: } ingo@65: } ingo@65: ingo@65: return (OutputMode[]) outs.toArray(new OutputMode[size]); ingo@65: } ingo@16: } ingo@16: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :