ingo@1115: /*
ingo@1115: * Copyright (c) 2010 by Intevation GmbH
ingo@1115: *
ingo@1115: * This program is free software under the LGPL (>=v2.1)
ingo@1115: * Read the file LGPL.txt coming with the software for details
ingo@1115: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@1115: */
ingo@1115:
ingo@478: package de.intevation.gnv.artifacts;
ingo@478:
ingo@478: import java.util.ArrayList;
ingo@478: import java.util.Collection;
ingo@478: import java.util.HashMap;
ingo@478: import java.util.Map;
ingo@478:
ingo@478: import javax.xml.xpath.XPathConstants;
ingo@478:
sascha@479: import org.apache.log4j.Logger;
ingo@478: import org.w3c.dom.Document;
ingo@478: import org.w3c.dom.Node;
ingo@478: import org.w3c.dom.NodeList;
ingo@478:
tim@1028: import de.intevation.artifactdatabase.DefaultArtifactFactory;
tim@1028: import de.intevation.artifactdatabase.ProxyArtifact;
sascha@1117: import de.intevation.artifacts.common.utils.XMLUtils;
tim@1028: import de.intevation.artifacts.Artifact;
tim@1028: import de.intevation.artifacts.ArtifactFactory;
ingo@1118: import de.intevation.artifacts.CallMeta;
ingo@1118: import de.intevation.artifacts.GlobalContext;
tim@1028: import de.intevation.gnv.artifacts.fis.SelectProductArtifact;
tim@1028: import de.intevation.gnv.artifacts.fis.product.DefaultProduct;
tim@1028: import de.intevation.gnv.state.DefaultInputData;
tim@1028:
ingo@478: /**
ingo@789: * This factory is called to create a {@link
ingo@789: * de.intevation.gnv.artifacts.fis.SelectProductArtifact} which lets the user
ingo@789: * select a product supported by the selected fis.
ingo@789: *
sascha@780: * @author Ingo Weinzierl
ingo@478: */
ingo@478: public class GNVProductArtifactFactory extends DefaultArtifactFactory {
ingo@478:
ingo@478: public static final String XPATH_REPLACE_NAME = "IDENTIFIER";
ingo@478:
ingo@478: public static final String XPATH_PRODUCT_ARTIFACT =
ingo@478: "artifact-database/artifacts/artifact[@name='"+XPATH_REPLACE_NAME+"']";
ingo@478:
ingo@478: public static final String XPATH_PRODUCT = "products/product";
ingo@478:
ingo@478: public static final String XPATH_PRODUCT_NAME = "@name";
ingo@478:
ingo@478: public static final String XPATH_PRODUCT_FACTORY = "artifact-factory";
ingo@478:
ingo@478: public static final String XPATH_PRODUCT_PARAMETER = "parameters/parameter";
ingo@478:
ingo@478: private Logger logger = Logger.getLogger(GNVProductArtifactFactory.class);
ingo@478:
ingo@478: private Map productFactories;
ingo@478: private Map products;
ingo@478:
ingo@478:
ingo@789: /**
ingo@789: * Constructor.
ingo@789: */
ingo@478: public GNVProductArtifactFactory() {
ingo@478: }
ingo@478:
ingo@789: /**
ingo@789: * Method to create an artifact. If the created artifact is from type
ingo@789: * ProxyArtifact
, a further ProductSelectArtifact is created
ingo@789: * which becomes embedded into the ProxyArtifact
.
ingo@789: * @param identifier UUID.
ingo@789: * @param context CallContext.
ingo@789: * @param data Some data.
ingo@789: * @return The created artifact.
ingo@789: */
ingo@478: @Override
ingo@1118: public Artifact createArtifact(
ingo@1118: String identifier,
ingo@1118: GlobalContext context,
ingo@1118: CallMeta meta,
ingo@1118: Document data
ingo@1118: ) {
ingo@478: // create a SelectProductArtifact for initial product selection
ingo@1118: Artifact artifact = super.createArtifact(identifier, context, meta, data);
ingo@478:
ingo@478: if (artifact instanceof ProxyArtifact) {
ingo@478:
ingo@478: SelectProductArtifact select = new SelectProductArtifact();
ingo@478: select.setProducts(products);
ingo@1118: select.setup(identifier, this, context, meta, data);
ingo@478:
ingo@478: ((ProxyArtifact) artifact).setProxied(select);
ingo@478: }
ingo@478:
ingo@478: return artifact;
ingo@478: }
ingo@478:
ingo@815:
ingo@478: @Override
ingo@478: public void setup(Document document, Node factoryNode) {
ingo@478: super.setup(document, factoryNode);
ingo@478:
ingo@478: String xpath = XPATH_PRODUCT_ARTIFACT.replace(XPATH_REPLACE_NAME, name);
ingo@478: Node artifact = (Node) XMLUtils.xpath(
ingo@478: document, xpath, XPathConstants.NODE);
ingo@478:
ingo@478: NodeList productNodes = (NodeList) XMLUtils.xpath(
ingo@478: artifact, XPATH_PRODUCT, XPathConstants.NODESET);
ingo@478:
ingo@478: if (productNodes == null) {
ingo@478: logger.warn("No products found for fis: " + name);
ingo@478: return;
ingo@478: }
ingo@478:
ingo@478: int productLength = productNodes.getLength();
ingo@478:
ingo@478: if (productLength != 0) {
ingo@478: productFactories = new HashMap(productLength);
ingo@478: products = new HashMap(productLength);
ingo@478:
ingo@478: parseProductFactories(document, productNodes);
ingo@478: }
ingo@478: }
ingo@478:
ingo@478:
ingo@478: public ArtifactFactory getArtifactFactoryByName(String name) {
ingo@478: return (ArtifactFactory) productFactories.get(name);
ingo@478: }
ingo@478:
ingo@478:
ingo@478: protected void parseProductFactories(Document document, NodeList products) {
ingo@478: int items = products.getLength();
ingo@478:
ingo@478: for(int i = 0; i < items; i++) {
ingo@478:
ingo@478: try {
ingo@478: Node product = products.item(i);
ingo@478:
ingo@478: String name = (String) XMLUtils.xpath(
ingo@478: product, XPATH_PRODUCT_NAME, XPathConstants.STRING);
ingo@478:
ingo@478: Node factoryNode = (Node) XMLUtils.xpath(
ingo@478: product, XPATH_PRODUCT_FACTORY, XPathConstants.NODE);
ingo@478:
tim@1028: String factoryClass = factoryNode.getTextContent().trim();
ingo@478:
ingo@478: if (factoryClass == null || factoryClass.equals("")) {
ingo@478: logger.warn("No artifact factory class found for " + name);
ingo@478: continue;
ingo@478: }
ingo@478:
ingo@478: Class cls = Class.forName(factoryClass);
ingo@478: ArtifactFactory factory = (ArtifactFactory) cls.newInstance();
ingo@478: factory.setup(document, factoryNode);
ingo@478:
ingo@478: productFactories.put(name, factory);
ingo@478: initializeProducts(product);
ingo@478: }
ingo@478: catch (ClassNotFoundException cnfe) {
ingo@478: logger.warn(cnfe, cnfe);
ingo@478: }
ingo@478: catch (InstantiationException ie) {
ingo@478: logger.warn(ie, ie);
ingo@478: }
ingo@478: catch (IllegalAccessException iae) {
ingo@478: logger.warn(iae, iae);
ingo@478: }
ingo@478: }
ingo@478: }
ingo@478:
ingo@478:
ingo@789: /**
ingo@789: * Initialize all products supported by the current fis.
ingo@789: */
ingo@478: protected void initializeProducts(Node productNode) {
ingo@478: String productName = (String) XMLUtils.xpath(
ingo@478: productNode, "@name", XPathConstants.STRING);
ingo@478:
ingo@478: NodeList parameterNodes = (NodeList) XMLUtils.xpath(
ingo@478: productNode, XPATH_PRODUCT_PARAMETER, XPathConstants.NODESET
ingo@478: );
ingo@478:
ingo@478: if (parameterNodes != null) {
ingo@478: int items = parameterNodes.getLength();
ingo@478: Collection inputParameter = new ArrayList(items);
ingo@478:
ingo@478: for (int j = 0; j < items; j++) {
ingo@478: Node parameterNode = (Node) parameterNodes.item(j);
ingo@478: String name = (String) XMLUtils.xpath(
ingo@478: parameterNode, "@name", XPathConstants.STRING);
ingo@478: String value = (String) XMLUtils.xpath(
ingo@478: parameterNode, "@value", XPathConstants.STRING);
ingo@478:
ingo@478: inputParameter.add(new DefaultInputData(name, value));
ingo@478: }
ingo@478:
ingo@478: products.put(
ingo@478: productName,
ingo@478: new DefaultProduct(productName, inputParameter, this.name)
ingo@478: );
ingo@478: }
ingo@478: }
ingo@478: }
sascha@836: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :